Template & Inheritance

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
34
35
#include <iostream>

class Base{
public:
	Base(){}
	virtual ~Base(){}
	virtual void show() const {
		std::cout << "Base::show()!" << std::endl;
	}
};
class A:public Base{
public:
	A(){}
	virtual ~A(){}
	virtual void show() const{
		std::cout << "A::show()!" << std::endl;
	}
};

template<typename T>
class Factory{
public:
	const T* operator()() const{
		return &t;
	}
private:
	T t;
};

int main(){
	const A* pA = Factory<A>()();
	pA->show();
	Factory<A>()()->show();
	return 0;
}


Output:
Base::show()!
A::show()!


Can anyone explain this? Thanks in advance!

Last edited on
 
const A* pA = Factory<A>()();


Factory<A>() creates an unnamed temporary object which contains an A. The temporary is then destroyed, destroying the contained A as well. You then call operator() on a destroyed object, returning a pointer to an object that has been destroyed. == undefined behavior.

EDIT: What I said above is somewhat right... the destructor for the unnamed temporary of Factory<A> is called after operator() returns, leaving you with a dangling pointer. The reason the second example works is exactly because the destructor of Factory<A> does not run until after show() returns.
Last edited on
Thank you very much! Jsmith...

In some way I am impressed and convinced by your opinion. Now I believe that the cause may/should be from TEMPORARY OBJECT issue. In spite of this, I need to figure out what the behavior exactly is.

Really appreciate what you did. Thank you again!!

Regards,
lyceum
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>

class Base{
public:
	Base(){
		std::cout << "Base() is called!" << std::endl;
	}
	virtual ~Base(){
		std::cout << "~~Base() is called!" << std::endl;
	}
	virtual void show() const {
		std::cout << "Base::show()!" << std::endl;
	}
};
class A:public Base{
public:
	A(){
		std::cout << "A() is called!" << std::endl;
	}
	virtual ~A(){
		std::cout << "~~A() is called!" << std::endl;
	}
	virtual void show() const{
		std::cout << "A::show()!" << std::endl;
	}
};

template<typename T>
class Factory{
public:
	const T* operator()() const{
		return &t;
	}
	Factory():t(T()){
		std::cout << "Factory() is called!" << std::endl;
	}
	~Factory(){
		std::cout <<"~~Factory() is called!" << std::endl;
	}
private:
	T t;
};

int main(){
	const A* pA = Factory<A>()();
	pA->show();
	Factory<A>()()->show();
	return 0;
}


Output:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Base() is called!
A() is called!
Factory() is called!
~~Factory() is called!
~~A() is called!
~~Base() is called!
Base::show()!
Base() is called!
A() is called!
Factory() is called!
A::show()!
~~Factory() is called!
~~A() is called!
~~Base() is called!


Thanks Jsmith...
You are right....
Topic archived. No new replies allowed.