class virtual function but no overload instead stack calling ( constructor like behavior )

Not really good at making titles.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class deep{
deep(){
     cout << "deep()" << endl;
}

void stackTrigger(){
    cout << "stackTrigger() - deep" << endl;
}
}

class shallow : public deep{
shallow(){
    cout << "shallow()" << endl;
}

void stackTrigger(){
    cout << "stackTrigger() - shallow" << endl;
}

}

int main(){
shallow c; c.stackTrigger();
return 0;
}




shallow()
deep()
stackTrigger() - shallow
stackTrigger() - deep

'stackTrigger()'
It's not possible but you have an idea what i'm trying to achieve now.
Could I possible do something like that somehow?

Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>

using namespace std;

class deep {
public:
	deep() {
		cout << "deep()" << endl;
	}
	
	void stackTrigger(){
		cout << "stackTrigger() - deep" << endl;
	}
};

class shallow : public deep {
public:
	shallow() {
			cout << "shallow()" << endl;
	}

	void stackTrigger(){
		cout << "stackTrigger() - shallow" << endl;
		deep::stackTrigger();
	}
};

int main() {
	shallow c;
	c.stackTrigger();
	return 0;
}
deep()
shallow()
stackTrigger() - shallow
stackTrigger() - deep
Is it possible to do the stack calling without manually typing it out?
The less human, less mistakes, less debug, less cost in development.
Last edited on
Is it possible to do the stack calling without manually typing it out?
The less human, less mistakes, less debug, less cost in development.


Really? Typing it out is more cost in development?

If you are worried about the extra 23 keystrokes required to call the base class functionality, why not change the name of your classes to "d" and "s" and the need of your functions to "a" and "b"?

The answer to this should be obvious. The clarity that longer names provides greatly aids in the understand-ability and maintainability of the code.

Typing out baseclass::function() clearly shows the programmers intentions of calling the base class functionality. And it allows the base class functionality to be called at the beginning, in the middle, or at the end of the derived class function, depending on the programmer's needs.

I guess there could be a keyword like SUPER_CALL or something that calls the base class functionality using the arguments passed in, but I don't think it really buys you anything.
We have a system at work with the same requirements. For example, derived::execute() is expected to call base::execute(). I had the same angst as you when we designed it.

It turns out that calling the base class method explicitly was a lifesaver! Sometimes we need to do:

1
2
3
4
5
DerivedXYZ::execute()
{
    doSomeWork();
    base::execute();
}

Now imagine if there was some whacky machinery in place that always called base::execute() at the beginning of DerivedXYZ::execute(). In that case, we'd have to do some code gymnastics to make it do what we wanted, even though what we wanted was pretty clear.

Yes, there were a few cases where someone forgot to call the base method, but those always turned up in unit testing or system testing.

One thing we DID do was a typedef to ensure we call the right base class. During development, sometimes we found that a class needed to be somewhere else in the hierarchy and we didn't want to have to change all the base class qualifiers:
1
2
3
4
5
6
7
8
typedef MultiSjob MultiNormalSjobBase;
class MultiNormalSjob : public MultiNormalSjobBase
{
...
execute() {
     MultiNormalSjobBase::execute();
     doStuff();
}



If you always want to call deep::stackTrigger(), no more, no less, no matter how deep the inheritance chain is, you could instead make the stackTrigger() function call a protected virtual function that the derived classes can override instead.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>

using namespace std;

class deep {
public:
	deep() {
		cout << "deep()" << endl;
	}
	
	void stackTrigger(){
		doStackTrigger();
		cout << "stackTrigger() - deep" << endl;
	}
protected:
	virtual void doStackTrigger() = 0;
};

class shallow : public deep {
public:
	shallow() {
		cout << "shallow()" << endl;
	}
protected:
	void doStackTrigger() override {
		cout << "stackTrigger() - shallow" << endl;
	}
};

int main() {
	shallow c;
	c.stackTrigger();
}
deep()
shallow()
stackTrigger() - shallow
stackTrigger() - deep
Topic archived. No new replies allowed.