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.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
In c++ is there a reson why you would pass a reference to a base class to a constructor of a derived class? Why would you want to do this?
Here is a basic example:
#include<iostream>
using namespace std;
class Base
{
int x;
public:
virtual void fun() = 0;
int getX() { return x; }
};
// This class ingerits from Base and implements fun()
class Derived: public Base
{
int y;
public:
Derived(Base& object);
void fun() { cout << "fun() called"; }
};
Typically, arguments are passed to constructors because the state of the arguments can be used to initialize the state of the object that is being constructed. Same applies to this case.
Non-const reference arguments can be (and nearly always are) used to modify the referred object.
In c++ is there a reason why you would pass a reference to a base class to a constructor of a derived class?
There is usually one reason why reference to an object would be passed to a constructor, does not really matter if that object type related to consttructed one or not - to construct this type you need information from that object. Using lvalue reference instead of const one could mean either bad design or ctor would need to modify passed object or keep non-const reference/pointer to it.
I would think the question is "why pass the base class reference instead of the derived class reference?". If so, the reason Base& is passed instead of Derived& is that the former allows you to pass an OtherDerived& reference, given that OtherDerived inherits Base. This is called polymorphism and is quite a thing in C++.
Here's pretty much the same question, but with a function instead of a constructor.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
When implementing an abstract class like this:
class Base
{
public:
virtual ~Base() = default;
virtual void foo() = 0;
};
Does this interface have to obey the rule of five i.e. do I have to add a copy constructor, copy assignment operator, move constructor and move assignment operator?
I'd figure that an instace of type Base can not be instantiated due to the pure virtual member function and thus providing default implementations for the other special member functions might serve no real purpose.
Is there any use-case/example that would require me to provide the other special member functions?
"abstract" is irrelevant here. A class needs its own copy constructor, copy assignment operator, etc. if it has data that won't be properly copied by the default versions. Full stop. The presence or absence of pure virtual functions does not change this. Your example doesn't have any data, so doesn't have an issue here.
Actually it is the contrary. I would consider deleting copying and assignment of a class that is supposed to be only an interface class to avoid slicing. Consider
class Base {
public:
virtual ~Base() {}
};
class D1 : public Base {
int i;
public:
~D1() override {}
};
class D2 : public Base {
int i;
double d;
public:
~D2() override {}
};
you could write something like this
vector<Base> vec;
D1 d;
D2 e;
vec.push_back(d);
vec.push_back(e);
. You would try to squeeze an object of size D2 into a much smaller object of type base. By deleting copy and assignment you do prevent the user or yourself doing that.
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.
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 5 years ago.
Improve this question
class A { int* a; };
class B : public A { int*b; };
int main() {
A* ptr = new B();
delete ptr;
}
class A is a pure virtual interface class and class B inherits from class A. When we delete ptr which destructor will be called? The one from the A class or the one from from the B class?
Comment: First of, why do you have code outside any function? Statements only make sense when there are within the body of a function, like main.
Assuming the statements you posted were supposed to go into main:
Answer:
delete ptr will call the destructor of A. The compiler will not 'think' any further than this.
Reason: All methods (including the destructor) are non-virtual by default. In your case, you did not specify that the destructor should be virtual. The compiler sees that you are calling the destructor on a A* pointer, so it calls the destructor of A.
What if I had specified that Class A destructor was virtual? Would it still call the destructor of Class A?
Answer: If it were virtual, it would call the destructor of B, because the actual type of the object would be determined during the execution of the program.
See more about virtual functions and polymorphism here.
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.