Re: Constructor Inheritance
make the base constructor private :)
Re: Constructor Inheritance
The base constructor is accessible, yes, but it is not inherited because this will not work:
Code:
class Base{
public:
Base(int x,int y){}
};
class Derived : public Base{
// no constructor, so the default one will be generated
};
int main()
{
Derived(5,6);// compile error, no such constructor for Derived.
}
Re: Constructor Inheritance
Quote:
Originally Posted by
Rajesh1978
How we conclude that the constructors are not inherited??
Because I can call the base class constructors like below which means that the the constructor is accissible .
Code:
class Base{
public:
Base(int x,int y){}
};
class Derived : public Base{
public:
Derived(int a,int b):Base(a,b) //I am calling the Base constructor
{
}
};
Thanks
The commented line should be: i am passing constructor's arguments
I'm sure that is called: "Passing constructor's arguments" (or something similar), that's not a actual function call of the constructor, if you need to explicit call the constructor you have a bigger problem with the design of class or class hierarchy.
The constructor of base class is called even if you don't pass parameters (the default c-tor or with default parameters), so you can write: Derived(int a,int b){} // and do something in the c-tor body, of course you need default base c-tor for that.
LE: That line actually says: When construct the "Base part" of Derived object run the Base constructor with the two parameters of the Derived constructor.
Re: Constructor Inheritance
In a similar line, I can give another example:
Code:
class Base
{
public:
void ConstructorMethod(int);
};
class Derived:public Base
{
public:
void ConstructorMethod(int,int);
};
int main()
{
Derived d;
d.ConstructorMethod(2,4);
// this is NOT possible
d.ConstructorMethod(2);
}
The second definition of ConstructorMethod hides the original definition. Same thing happen with CTORs - they are always defined, implicitly or explicitly. The derived definition hides the base' version. To call the base class' you can:
Code:
d.Base::ConstructorMethod(2);
And this is also possible!
Code:
class Base {
public: Base(int = 0); // Default just for brevity
};
class Derived{};
...
Derived d;
d.Base::Base(10); // YES - you can call.
This way you can say that constructors are inherited, but just hidden!
Re: Constructor Inheritance
Sorry Ajay, you are wrong. The standard says constructors cannot be called like that. Comeau rejects this code correctly, tho MSVC10 compiles it without a problem (compiler bug?)...
Code:
struct Base
{
Base( int x ) : X( x )
{}
int X;
};
struct Derived : Base
{
Derived() : Base( 5 )
{}
};
int main()
{
Derived can_do;
can_do.Base::Base(10);
return 0;
}
Quote:
Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing. All rights reserved.
MODE:strict errors C++ C++0x_extensions
"ComeauTest.c", line 18: error: a constructor or destructor may not have its address
taken
can_do.Base::Base(10);
^
1 error detected in the compilation of "ComeauTest.c".
Constructors are not hidden, nor inherited. Constructors, destructor and copy assignment operators are never inherited. To do so would imo go against the whole concept of type-safety.
Re: Constructor Inheritance
Quote:
Originally Posted by Russco
Constructors, destructor and copy assignment operators are never inherited. To do so would imo go against the whole concept of type-safety.
hmm... a search for "not inherited" only brings up a sentence in C++03 that confirms that destructors are not inherited. Where does the standard state this more specifically? In particular, does it really state that copy assignment operators are not inherited?
Re: Constructor Inheritance
The standard states that constructors do not have a name, so therefore cannot be explicitly called by name. I'm not sure if it mentions that they are not inherited, but for sure TCPPPL does and we know who wrote that :). It would go totally against type safety for constructors, destructors or copy assignment to be inherited. They must be accessible to the derived class but they are not members of the derived class which they would be had they been inherited.
Re: Constructor Inheritance
Actually I may be wrong about copy assignment. I checked TCPPPL and cant find the info, so I checked Thinking in C++ and thats where this info was stated but I think its wrong because assignment can be virtual so assignment must be inherited and hidden though virtual copy assignment doesn't make much sense to me, but constructors on the other hand I dont think are inherited at all, all they need to be is accessible to the derived class in the same way destructors are.
Re: Constructor Inheritance
Quote:
Originally Posted by
Russco
Sorry Ajay, you are wrong. The standard says constructors cannot be called like that.
Look closer: He's not calling constructors. Just normal methods called ConstructorMethod(). Slightly confusing, perhaps, but perfectly fine.
Re: Constructor Inheritance
Quote:
Originally Posted by
Lindley
Look closer: He's not calling constructors. Just normal methods called ConstructorMethod(). Slightly confusing, perhaps, but perfectly fine.
Not necessarily confusing. It's called the named constructor idiom. It is almost completely free from a performance point of view, and can be quite useful when constuctor arguments are not quite enough to set the constructors apart, or to really convey the nuances between the different constructors.
Re: Constructor Inheritance
Quote:
Originally Posted by
Lindley
Look closer: He's not calling constructors. Just normal methods called ConstructorMethod(). Slightly confusing, perhaps, but perfectly fine.
Oh really?
Code:
d.Base::Base(10); // YES - you can call.
This is what I was talking about specifically. This is not allowed. When constructors are called by a programmer, its implicitly or as part of a type conversion which is still an implicit call. Explicitly calling a constructor is what compilers do, not programmers.
Re: Constructor Inheritance
Quote:
Originally Posted by
Russco
Sorry Ajay, you are wrong. The standard says constructors cannot be called like that. Comeau rejects this code correctly, tho MSVC10 compiles it without a problem (compiler bug?)...
Not a bug. It compiles in VC6, VC7, VC7.1, VC8, VC9 and VC10 as well. I do not know about standard as such, and never used Comeau compiler.
Quote:
Constructors are not hidden, nor inherited. Constructors, destructor and copy assignment operators are never inherited. To do so would imo go against the whole concept of type-safety.
I can take that only for CTOR. Destructor ARE inherited, otherwise virtual destructor wouldn't make sense. Also destructors can be called explicitly using X::~X() syntax.
Also, assignment operator are inherited as you mentioned.
Again I don't know about your compiler.
Anyway, my point was not about standard - but basic concept behind CTOR inheritance!
Re: Constructor Inheritance
Quote:
Originally Posted by
Ajay Vijay
In a similar line, I can give another example:
Code:
class Base
{
public:
void ConstructorMethod(int);
};
class Derived:public Base
{
public:
using Base::ConstructorMethod; //monarch_dodra: add this line here
void ConstructorMethod(int,int);
};
int main()
{
Derived d;
d.ConstructorMethod(2,4);
// this is NOT possible
d.ConstructorMethod(2);
}
The second definition of
ConstructorMethod hides the original definition. Same thing happen with CTORs - they are always defined, implicitly or explicitly. The derived definition hides the base' version.
If you add "using Base::ConstructorMethod" inside Derived allows you to not hide the original definition, and write
Code:
// this is NOW possible
d.ConstructorMethod(2);
The whole hiding thing is there more as a "safety mechanism" than a real feature anyways. This is because it is usually not really recommended to re-define a function in a derived class, and forcing the user to write the using declaration is like forcing him to say "Yes, I know what I am doing, and I take full responsabilty"
Re: Constructor Inheritance
Quote:
Originally Posted by Ajay Vijay
I can take that only for CTOR. Destructor ARE inherited, otherwise virtual destructor wouldn't make sense. Also destructors can be called explicitly using X::~X() syntax.
As I mentioned earlier:
Quote:
Originally Posted by C++03 Section 10.3 Paragraph 4
Even though destructors are not inherited, a destructor in a derived class overrides a base class destructor declared virtual; see 12.4 and 12.5.
Re: Constructor Inheritance
Been playing with virtual copy assignment operators. Although in Base properties recognizes the operator as having the 'IsVirtual' property true, I cant find any signature in Derived that doesn't include the virtual keyword for which the same property is true. This is making it look like copy assignment is not inherited and virtual is all but ignored. How should a virtual copy assignment operator behave? It really doesn't make any sense to me.
As for virtual destructors as LL pointed out, the slot in the vtable is inherited but the destructor itself isn't. The base class destructor will be called implicitly by the compiler so it has to be accessible to the derived class but at no time does Base::~Base become a member of Derived. The standard allows explicitly calling destructors( basically only for placement new use) but does not allow the same latitude with constructors.
Re: Constructor Inheritance
Quote:
Been playing with virtual copy assignment operators. Although in Base properties recognizes the operator as having the 'IsVirtual' property true, I cant find any signature in Derived that doesn't include the virtual keyword for which the same property is true. This is making it look like copy assignment is not inherited and virtual is all but ignored. How should a virtual copy assignment operator behave? It really doesn't make any sense to me.
Speaking of which, what exactly is an override of a virtual copy assignment operator? My intuition leads me to:
Code:
#include <iostream>
class X
{
public:
virtual X& operator=(const X& other)
{
std::cout << "X copy assignment" << std::endl;
return *this;
}
virtual ~X() {}
};
class Y : public X
{
public:
Y& operator=(const X& other)
{
std::cout << "Y override of X copy assignment" << std::endl;
return *this;
}
};
class Z : public X
{
public:
Z& operator=(const X& other)
{
std::cout << "Z override of X copy assignment" << std::endl;
return *this;
}
};
int main()
{
Y y;
Z z;
X& r = y;
r = z;
}
With the MinGW port of g++ 3.4.5, I get the output of "Y override of X copy assignment", which is exactly what I would expect if some other virtual member function was involved. That also makes the most sense to me concerning how a virtual copy assignment operator should behave, if we can consider them to be copy assignment operators even though the parameters are of type reference to the base class rather than reference to the current class.
Re: Constructor Inheritance
Hmm maybe an IDE bug in msvc10. The function behaves virtually so I guess must be an inheritable member unless virtual copy assignment operates in the same way as virtual destructors, but my IDE still insists Y::operator =(const X&) is a nonvirtual but then if I add trivial destructors to Y and Z it also insists they are non-virtual.
Re: Constructor Inheritance
Quote:
Originally Posted by
Ajay Vijay
Not a bug. It compiles in VC6, VC7, VC7.1, VC8, VC9 and VC10 as well. I do not know about standard as such, and never used Comeau compiler.
I'd say it should be considered a bug. The standard states that ctors have neither names nor addresses, and that they should only be used to initialize an object. MSVC is allowing you to explicitly call a ctor and run a ctor on an object that's already been constructed.
Re: Constructor Inheritance
Quote:
Originally Posted by Speedo
I'd say it should be considered a bug.
I would not call it as bug, but non-compliance to the standard.
Re: Constructor Inheritance
Quote:
Originally Posted by
Lindley
The base constructor is accessible, yes, but it is not inherited because this will not work:
Ohk I got it.
So there are things that will be accessible but not inherited like constructors.
I got another problem just related to accessibility like below
Code:
class Base{
int x;
};
class Derived : public Base{
int y;
};
if i see the sizeof (Derived) it is giving me 8. (consider int size is 4)
But I know that private variables are never inherited.
But is it like it comes to the Derived class but is not accessible and adds 4 bytes to the size.
Correct me if I am wrong
Re: Constructor Inheritance
Quote:
Originally Posted by
Rajesh1978
But I know that private variables are never inherited.
Not quite true. Inheritance is an IS-A relationship, so a Derived IS-A Base. That means that the Derived must contain all members of Base.
However, some of those members, specifically the private ones, may not be accessible to the methods of Derived. So what good are they?
Well, keep in mind that some methods of Base may be inherited wholesale, both signature and implementation. Any public or protected method of Base which is not virtual fits this category, as well as any virtual methods which are not overridden by Derived. These methods will be exposed as part of Derived and accessible, but since they're actually Base functions, they're able to access the private members of Base just fine.
Re: Constructor Inheritance
Whatever there in the Base will come to Derived and increase the size(if attribute) as I showed just before.
Irrespctive of whether it is private or public.
private variables of Base are not accessible directly in the child but we can access it indirectly.
Am I correct
Re: Constructor Inheritance
Private members are inherited, they are not accessible.
For example:
Code:
Derived d;
int* p= (int*)&d;
*p=10; // Sets Base::x to 10
Though, it should not be used! :cool: