This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Trouble with inheritance of operator= in C++
hello everyone, let's assume I have two classes:
Base{}; //inside I have operator=
Derived{}; //inside I don't have operator=
why this one is working perfectly:
Derived der1, der2;
der1=der2; //<-here I know that it actually calls my Base::operator=
and this one is not:
Derived der1;
Base bas1;
der1=bas1; //<-here why can't call Base::operator=?
The implicitly declared copy assignment operator looks like
Derived& operator=(const Derived&);
This implicitly declared function calls operator= for each base class and member subobject (this is why the Base class operator= overload is called).
bas1 is of type Base, not Derived, and there is no implicit conversion from Base to Derived, hence it doesn't work. You would need to declare an appropriate assignment operator in order to support assigning an object of type Base to an object of type Derived (this would be a bit unusual though).
That's because
Derived& Derived::operator=(Derived const&);
hides the assignment
Base& Base::operator=(Base const&);
from the base class. This has something to do with name lookup and scopes. Check your favorite C++ book on hiding.
Related
This question already has answers here:
C++ Virtual operator delete?
(3 answers)
Closed 5 years ago.
I'm trying to overload class specific operators new and delete to use custom allocator, for some abstract base class:
class Base abstract
{
public:
void * operator new (size_t sz)
{
return tc_malloc(sz);
}
void operator delete(void* p){
tc_free(p)
}
and I have a class "Derived" inherits from base (not directly, it's a complex inheritance chain, but eventually it's derived from base), and have:
a = new Derived();
.
.
delete a;
now a weird thing happens.. my operator new is called, calling tc_malloc, but for "delete a;" operator delete is called from delete_scalar.cpp (the default delete operator) this of course causes an exception as it tries to free memory not allocated by malloc.
any idea what could cause this?
So I found the problem:
it's because delete was called on an incomplete class.
more specifically, I had an .h file which looked something like this:
class A; //forward declaration
class User {
A* a;
User();
~User(){
delete a; //this is the problem
}
so delete is called on an incomplete type, which has undefined behavior.
so neither the destructor nor the class specific delete operator is called here
I think C++ Virtual operator delete? could help understand what is going on here.
If I understand it correctly, always the delete operator of the most derived class is used, therefore it must use the one from Derived. And it seems, since you didn't declare one for Derived, the default operator is used.
This question already has answers here:
I defined a non-copy constructor; will a copy constructor still be implicitly defined?
(3 answers)
Closed 6 years ago.
I am trying to learn C++ OOP concepts through an online tutorial where I encountered a code snippet illustrating operator overloading.
The code is shown below:
class MyClass{
int var;
public:
Myclass(int value=0){
var = value;
}
Myclass operator+(Myclass &obj){
Myclass newobj;
newobj.var = this->var + obj.var;
return newobj;
}
};
Suppose I call the operator in the main function like so:
int main(){
...
obj3 = obj2 + obj1;
...
}
During earlier tutorials on Classes, I read about why copy constructors require all parameters to be passed by reference since they themselves are the definition of how to copy two class objects. So, as far as I understand, copy constructors are a must when one has to copy objects of a class.
In the above code snippet, it appears to me that the compiler will try to "copy" the values of newobj onto the L_value in the main() function (obj3). But how is this possible without a copy constructor defined. Have I misunderstood something here?
Thank you for your help!
http://en.cppreference.com/w/cpp/language/copy_constructor#Implicitly-declared_copy_constructor
If you are using standard C++ 2003 or older copy constructor is always implicitly defined (generated by compiler) for any class T unless:
T has non-static data members that cannot be copied (have deleted, inaccessible, or ambiguous copy constructors);
T has direct or virtual base class that cannot be copied (has deleted, inaccessible, or ambiguous copy constructors);
T has direct or virtual base class with a deleted or inaccessible destructor;
If you are using standard C++ 2011 or newer copy constructor is always implicitly defined (generated by compiler) for any class T unless:
T has non-static data members that cannot be copied (have deleted, inaccessible, or ambiguous copy constructors);
T has direct or virtual base class that cannot be copied (has deleted, inaccessible, or ambiguous copy constructors);
T has direct or virtual base class with a deleted or inaccessible destructor;
T has a user-defined move constructor or move assignment operator;
T is a union and has a variant member with non-trivial copy constructor;
T has a data member of rvalue reference type.
Also keep in mind that
a = b;
is not primarily calling copy-constructor but copy-assignment. That in turn is also implicitly defined (auto-generated) if your class if suitable.
For details see: http://en.cppreference.com/w/cpp/language/copy_assignment#Implicitly-declared_copy_assignment_operator
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Can someone explain how this overloaded operator is called? I understand what the dynamic cast and the conditional ternary do, but I don't understand the operator.
header file:
// ------------------------------------------------------
Class Base
{
public:
Base ();
operator Derived &();
private:
Base * me;
}
//--------------------------------------------------
Class Derived : public Base
{
public:
Derived ()
}
//----------------------------------------------------
inline Base::operator Derived &() {return *(dynamic_cast<Derived *>(me?me:this));}
Source file:
Base::Base()
{
me = new Derived()
}
The operator operator Derived &() is a conversion operator:
12.3.2/1 A member function of a class X having no parameters with a name of the form
conversion-function-id:
operator conversion-type-id
(...)
specifies a conversion from X to the type specified by the
conversion-type-id. Such functions are called conversion functions. No
return type can be specified.
So it converts a Base object into a reference to Derived.
Attention: This kind of construct seems extremely weird and dangerous: it is a downcasting without care. If the object on which you use this operator would not be a Derived (for example a "pure" Base object or a another class derived from Base but not from Derived) the dynamic_cast would return a nullptr, which would cause UB:
8.3.2/5: (...) Note: in particular, a null reference cannot exist in a well-defined program, because the only way to create such a
reference would be to bind it to the “object” obtained by indirection
through a null pointer, which causes undefined behavior.
This question already has answers here:
Order of calling base class constructor from derived class initialization list
(3 answers)
Closed 8 years ago.
I need to know when the constructors of basis classes are called in the call of a derived class constructor.
Small example:
class Base1
{...}
class Base2
{...}
class Derived : Base1,Base2
{...}
int main (int argc, char** argv)
{
Derived Child;
}
With the command Derived Child; the constructor of Derived is called, but I have read that before the Derived class constructor is executed all base constructors are executed, i.e. constructors of Base1 and Base2.
So I am wondering how the event order would be if the constructor of class Derived looked like this
Derived::Derived (Parameters)
: //initialization list
Base2 (Parameters)
{...}
Is the constructor of class Base2 now called in the initialazation list of constructor Derived or is it called before. Furthermore are all base class constructors called at the beginning of the call of constructor Derived or when the initialization list of class Derived constructor starts.
greetings
streight
Order of call of constructors is 1st Base class then derived class.
In current example
Order of call of constructors is as :
Basis1
Basis2
Derived
If we change class definition to
class Derived : Basis2,Basis1
then order of constructor calls will be:
Basis2
Basis1
Derived
Base class constructor are always called before derived class, whether called explicitly from initialization list or not.
This question already has answers here:
call to pure virtual function from base class constructor
(8 answers)
Closed 5 years ago.
class a //my base class
{
public:
a()
{
foo();
}
virtual void foo() = 0;
};
class b : public a
{
public:
void foo()
{
}
};
int main()
{
b obj; //ERROR: undefined reference to a::foo()
}
Why it gives me error? The pure virtual foo is defined. What do I need to change in my code to make it work? I need pure virtual method from base class be called in its constructor.
Calling virtual functions in a constructor is recognised as a bad thing to do.
During base class construction of a derived class object, the type of
the object is that of the base class. Not only do virtual functions
resolve to the base class, but the parts of the language using runtime
type information (e.g., dynamic_cast (see Item 27) and typeid) treat
the object as a base class type.
So your instantiation of b invokes the a constructor. That calls foo(), but it's the foo() on a that gets called. And that (of course) is undefined.
Quoted from a book "Let Us C++"by Yashwant Kanetkar
It is always the member function of the current class , is called.That
is , the virtual mechanism doesn't work within the constructor
So, the foo() of class a gets called.
Since it is declared pure virtual, it will report an error
foo function is called in class a's constructor, and at that time, object b has not been fully constructed yet, hence it's foo implementation is unavailable.
Quoted from "Effective C++":
Don't call virtual functions during construction or destruction,
because such calls will never go to a more derived class than that of
the currently executing constructor or destructor