here is the thing, I want to (probably not the best thing to do) have the ability to call some class constructor that receives as a parameter a pointer to the class who's calling (ufff!!!). Well in code looks better, here it goes, as I do it in C#.
public class SomeClass
{
SomeOtherClass someOtherClass;
//Constructor
public SomeClass(SomeOtherClass someOtherClass)
{
this->someOtherClass = someOtherClass;
}
}
public class SomeOtherClass
{
public SomeOtherMethod()
{
SomeClass c = new SomeClass(this);
}
}
So, How can I achieve the same result in c++?
Thanx in advance.
class SomeOtherClass; // forward declaration (needed when used class is not visible)
class SomeClass
{
SomeOtherClass *someOtherClass;
public:
SomeClass(SomeOtherClass *some) : someOtherClass(some)
{} // this is called initialization at constructor (not assignment)
}
class SomeOtherClass
{
public:
SomeOtherMethod()
{
SomeClass *c = new SomeClass(this);
}
}
Having answered your requirements above, also note that in C++ you really don't need to declare objects always with new. If you declare,
SomeOtherClass someOtherClass;
then it means that you have an object of SomeOtherClass named someOtherClass.
probably not the best thing to do
It might not be a bad idea. However, every time you use pointers in C++, you must be completely clear about how it will be used: what kind of thing is being pointed to (not just the type of the pointer, but scalar vs. array, etc.), how the pointed-at thing gets there (e.g. via new? As part of some other object? Something else?), and how it will all get cleaned up.
How can I achieve the same result in c++?
Almost identically, except of course that C++ does not use new when you create a local instance by value (so we instead write SomeClass c = SomeClass(this);, or more simply SomeClass c(this);), and we must be aware of the pointer vs. value types (so SomeClass::someOtherClass is now a SomeOtherClass *, which is also the type we accept in the constructor). You should also strongly consider using initialization lists to initialize data members, thus SomeClass::SomeClass(SomeOtherClass* someOtherClass): someOtherClass(someOtherClass) {}.
You can do pretty much the same thing in C++ as well:
class B;
class A
{
public:
A (B * b) : pb (b) { }
private:
B * pb;
};
class B
{
public:
B () : a (this) { }
private:
A a;
};
The question is, do you really need that?
Maybe like this :)
class SomeOtherClass;
class SomeClass
{
private:
SomeOtherClass * someOtherClass;
public:
SomeClass(SomeOtherClass *someOtherClass)
{
someOtherClass = someOtherClass;
}
};
class SomeOtherClass
{
public:
void SomeOtherMethod()
{
SomeClass *c = new SomeClass(this);
}
};
'this' is a pointer-to-const in member functions (methods) declared as const.
So:
void f1(X* p);
void f2(const X* p);
class X {
void m1() {
f1(this); // OK
f2(this); // also OK
}
void m2() const {
f2(this); // OK
f1(this); // error, 'this' is a pointer to const X
}
};
Related
class Class1 //Would be object mClass1
{
public:
void Function1()
{
a++;
}
private:
int a = 0;
Class2 mClass2;
}
(Editing in a space here to clarify Class2 is not defined after Class1; they are in separate files.)
class Class2 //Would be object mClass2
{
public:
Function2()
{
Function1(); // Would be from mClass1
}
}
So Class1 creates an instance of a Class2 object, and that Class2 object has a member function that wants to access the "parent" object's member function, without using inheritance.
I don't know what I specifically need to search for to learn about this. Does it have to do with dereferencing a new pointer? Constructor type/initialization? Does it have a terminology? "Nested classes" bring up classes defined inside another class, which is not what this is.
Without inheritance there is no way to get the 'parent class'. So instead you should just pass the function as a parameter, maybe in the constructor of class 2 if you use it multiple times. See for example: https://www.cprogramming.com/tutorial/function-pointers.html
You cannot do this. Class2 is not known yet when you define Class1, so the Class1::mClass2 data member cannot possibly be created. But this problem can be solved by defining Class2 before Class1, and implementing Class2::Function2() outside the class and only after Class1.
As for calling Function1() inside Function2(), Class2 needs to know the object on which to call Function1(). You could use a reference member for that that you initialize in the constructor:
// Forward-declaration of Class1 so that Class2 will be able to define
// references or pointers to Class1.
class Class1;
class Class2
{
public:
// Constructor that requires a reference to our parent object.
explicit Class2(Class1& parent)
: parent_(parent)
{ }
// Just declare the function. We need to implement it later, outside
// this class definition because Class1 is not fully known yet and as
// a result we can't have calls to Function1() because the compiler
// doesn't know that function yet.
void Function2();
private:
// This is just a reference, so it works even if Class1 is not fully
// known yet.
Class1& parent_;
};
class Class1
{
public:
void Function1() { /* ... */ }
private:
int a = 0;
Class2 mClass2{*this}; // Pass ourself as the parent object.
};
// Class1 is fully known now, so we can do calls to Function1().
inline void Class2::Function2()
{
parent_.Function1();
}
This will work, but it has an important implication: it disables the assignment operator of Class2. This is probably what you want in this case, because two copies of Class2 should probably not have the same Class1 parent object.
However, I don't see why you need to do this. It complicates matters for no good reason. Why not simply pass the Class1 object that Function2() should use as a function argument instead? So:
class Class1;
class Class2
{
public:
void Function2(Class1& c1_obj);
};
class Class1
{
public:
void Function1() { /* ... */ }
private:
int a = 0;
Class2 mClass2;
};
inline void Class2::Function2(Class1& c1_obj)
{
c1_obj.Function1();
}
So whenever Class1 needs to call Class2::Function2(), just pass *this to it. It's simpler and doesn't have the drawbacks of holding a reference or pointer to another object.
With canonic classes - no way to do this, because Class2 is incomplete within Class1 and if you declare Class2 inside of Class1 (as a nested class), it wouldn't have access to Class1, because Class1 incomplete!
Looks like an unsolvable paradox? It is unsolvable in OOP land, but can be dodged just like Nikos had shown. But the problem of undefined types in some cases can be resolved in C++ or similar concept-oriented languages by using CRTP - Curiously recurring template.
If it is possible or not in your use-case and how complex it would be depending on what purpose you pursue. Here is an example of a paradoxical CRTP behavior - a member of base class is able to call a member of derived class:
#include <iostream>
template < class T>
class Base {
public:
template <class U>
struct Accessor : public U {
static void evoke_foo( T& obj)
{
return (obj.*(static_cast< void(T::*)() >(&Accessor::foo))) ();
}
};
void evoke( )
{
Accessor<T>::evoke_foo( *static_cast<T*>(this) );
}
};
class Derived : public Base<Derived> {
protected:
void foo() { std::cout << "Foo is called" << std::endl; }
};
int main()
{
Derived a;
a.evoke(); // evoke belongs to base.
}
Now if we'd want to determine return type of foo() automatically here, this would become an insanely complex piece of code. Some problems like that are solved in implementations of standard namesake of evoke method.
I've got a base class that has a virtual function. I want to call that class during the construction because I want the function called for each of the derived classes. I know I can't call a virtual function during construction, but I can't think of an elegant (i.e., avoid repeating code) solution.
What are some work arounds to calling a virtual function during construction?
The reason I want to avoid this is because I don't want to have to create constructors that just call the base class.
class A {
public:
A() {
read();
}
// This never needs to be called
virtual void read() = 0;
}
class B:A {
public:
B():A() { };
read() { /*Do something special for B here.*/ }
}
class C:A {
public:
C():A() { };
read() { /*Do something special for C here.*/ }
}
PS: The Python way of doing this is simply to raise NotImplementedError in A::read(). I'm returning to C++ and I'm more rusty than I thought.
The FAQ perspective.
This is a Frequently Asked Question.
See the C++ FAQ item titled “Okay, but is there a way to simulate that behavior as if dynamic binding worked on the this object within my base class's constructor?”.
It’s very often a good idea to check the FAQ (and generally, googling or altavista’ing) before asking.
The question as “Derived class specific base initialization”.
To be clear, while the literal question above is
“What are some work arounds to calling a virtual function during construction?”
it is evident that what’s meant is
“How can a base class B be designed so that each derived class can specify part of what goes on during B construction?”
A major example is where C style GUI functionality is wrapped by C++ classes. Then a general Widget constructor might need to instantiate an API-level widget which, depending on the most derived class, should be a button widget or a listbox widget or whatever. So the most derived class must somehow influence what goes on up in Widget’s constructor.
In other words, we’re talking about derived class specific base construction.
Marshall Cline called that “Dynamic Binding During Construction”, and it’s problematic in C++ because in C++ the dynamic type of an object during class T construction and destruction, is T. This helps with type safety, in that a virtual member function is not called on a derived class sub-object before that sub-object has been initialized, or its initialization has started. But a major cost is that DBDI (apparently) can’t be done in a way that is both simple and safe.
Where the derived class specific init can be performed.
In the question the derived class specific action is called read. Here I call it derived_action. There are 3 main possibilities for where the derived_action is invoked:
Invoked by instantiation code, called two-phase construction.
This essentially implies the possibility of having a mostly unusuable not fully initialized object at hand, a zombie object. However, with C++11 move semantics that has become more common and accepted (and anyway it can be mitigated to some extent by using factories). A main problem is that during the second phase of construction the ordinary C++ protection against virtual calls on uninitialized sub-objects, due to dynamic type changes during construction, is not present.
Invoked by Derived constructor.
For example, derived_action can be invoked as an argument expression for the Base constructor. A not totally uncommon technique is to use a class template to generate most derived classes that e.g. supply calls of derived_action.
Invoked by Base constructor.
This implies that knowledge of derived_action must be passed up to the constructor, dynamically or statically. A nice way is to use a defaulted constructor argument. This leads to the notion of a parallel class hierarchy, a hierarchy of derived class actions.
This list is in order of increasing sophistication and type safety, and also, to the best of my knowledge, reflects the historical use of the various techniques.
E.g. in Microsoft’s MFC and Borland’s ObjectWindows GUI early 1990’ libraries two-phase construction was common, and that kind of design is now, as of 2014, regarded as very ungood.
This is the factory method approach, putting the factory into the base class:
class A {
public:
virtual void read() = 0;
template<class X> static X* create() {X* r = new X;X->read();return X;}
virtual A* clone() const = 0;
};
class B : public A {
B():A() { };
friend class A;
public:
void read() { /*Do something special for B here.*/ }
B* clone() const {return new B(*this);}
};
class C : public A {
C():A() { };
friend class A;
public:
void read() { /*Do something special for C here.*/ }
C* clone() const {return new C(*this);}
};
Added a clone-method with covariant return type as a bonus.
Using CRTP:
class A {
public:
// This never needs to be called
virtual void read() = 0;
virtual A* clone() const = 0;
};
template<class D, class B> struct CRTP : B {
D* clone() {return new D(*this);}
static D* create() {return new D();}
};
class B : public CRTP<B, A> {
B() { };
public:
void read() { /*Do something special for B here.*/ }
};
class C : public CRTP<C, A> {
C() { };
public:
void read() { /*Do something special for C here.*/ }
};
One way to achieve this, would be simply to delegate it to another class (that is perhaps a friend) and can be sure to be called when fully constructed.
class A
{
friend class C;
private:
C& _c; // this is the actual class!
public:
A(C& c) : _c(c) { };
virtual ~A() { };
virtual void read() = 0;
};
class B : public A
{
public:
B(C& c) : A(c) { };
virtual ~B() { };
virtual void read() {
// actual implementation
};
};
class C
{
private:
std::unique_ptr<A> _a;
public:
C() : _a(new B(*this)) { // looks dangerous? not at this point...
_a->read(); // safe now
};
};
In this example, I just create a B, but how you do that can depend on what you want to achieve and use templates on C if necessary, e.g:
template<typename VIRTUAL>
class C
{
private:
using Ptr = std::unique_ptr<VIRTUAL>;
Ptr _ptr;
public:
C() : _ptr(new VIRTUAL(*this)) {
_ptr->read();
};
}; // eo class C
The workaround is to call the virtual function after construction. You can then couple the two operations (construction + virtual call) in factory function. Here is the basic idea:
class FactoryA
{
public:
A *MakeA() const
{
A *ptr = CreateA();
ptr->read();
return ptr;
}
virtual ~FactoryA() {}
private:
virtual A *CreateA() const = 0;
};
class FactoryB : public FactoryA
{
private:
virtual A *CreateA() const { return new B; }
};
// client code:
void f(FactoryA &factory)
{
A *ptr = factory.MakeA();
}
As mentioned by Benjamin Bannier, you can use CRTP (a template which defines the actual read() function.) One problem with that method is that templates have to always be written inline. That can at times be problematic, especially if you are to write really large functions.
Another way is to pass a function pointer to the constructor. Although, in a way, it is similar to calling the function in your constructor, it forces you to pass a pointer (although in C++ you could always pass nullptr.)
class A
{
public:
A(func_t f)
{
// if(!f) throw ...;
(*f)();
}
};
class B : A
{
public:
B() : A(read) {}
void read() { ... }
};
Obviously, you have the "can't call other virtual functions" problem within the read() function and any function it calls. Plus, variable members of B are NOT yet initialized. That is probably a much worst problem in this case...
For that reason, writing it this way is safer:
B() : A()
{
read();
}
However, in cases like that, that may be the time when you an some for of init() function. That init() function can be implemented in A() (if you make it accessible: i.e. use public A when deriving) and that function can call all the virtual functions as expected:
class A
{
public:
void init()
{
read();
}
};
class B : public A
{
public:
...
};
I know a lot of people say that an init() function is evil because people who create a B object now need to know to call it... but there isn't much else you can do. That being said, you could have a form of factory, and that factory can do the init() call as required.
class B : public A
{
public:
static B *create() { B *b(new B); b->init(); return b; }
private:
B() { ... } // prevent creation without calling create()
};
Suppose we have an Abstract class and child (derived from abstract) classes. I know we can instantiate from derivedClass like this:
AbstractBase *foo = new DerivedClass1();
But, is this the right way to define the top line code:
AbstractBase foo = *(new DerivedClass1());
I don't want to declare the Abstract class via pointer. But, What is the best way to do this and manage the memeory leak?
Thanks a lot
AbstractBase foo = *(new DerivedClass1()); will try to construct an instance of AbstractBase (which you can't do, it's abstract) using a constructor which takes an object of type DerivedClass1 (or something it's convertible to.
If you don't want to end up with a pointer to AbstractBase, but you do want to use new to allocate the object dynamically, then you probably want:
AbstractBase& foo = *(new DerivedClass1());
to define a reference to AbstractBase from your new DerivedClass1
Here is a very simple example of how to "chain" copy constructors. Note that the syntax may be a bit off, but this is the general idea:
class ABase {
public:
ABase(const ABase& ab) {
basevar = ab.getBasevar();
}
int getBasevar() { return basevar; }
private:
int basevar;
};
class c1 : public ABase {
public:
c1(const c1& c) : ABase(c) {
cvar = c.getCvar();
}
private:
int cvar;
};
In particular, note the use of the : operator between the function declaration and definition; this space allows for multiple direct assignments in a constructor function (possibly in other functions as well) and its content is called an "initialization list". Note also this answer which details some more examples.
As far as I know it is not possible to call the constructor of the base class. The only way I know is this:
MyClass::MyClass(/* args */) : Base(/* args */)
{
// ...
}
but this would invoke the constructor at the beginning.
Is there any way to call it somewhere else in the constructor? Something like this:
MyClass::MyClass(/* args */)
{
// ... instructions
Base::Base(/* args */);
// ... other_instructions
}
According to this What are the rules for calling the superclass constructor? question I understand there is no way but I read here and I guessed it was possible, but if I try I get:
error: invalid use of 'class Base'.
Am I doing something wrong? Is it possible to do this some way or is there any other possible solution to this need?
Thanks!
EDIT: I understand I forgot a key point: the base class is part of a framework, and therefore it would be good not to have to modify it, if possible.
If the base class constructor takes at least one argument, you could use a helper function like this:
int DoStuffBeforeCtorAndForwardInt(int arg, Foo foo)
{
DoStuff(arg, foo);
return arg;
}
MyClass::MyClass(int arg, Foo foo)
: Base(DoStuffBeforeCtorAndForwardInt(arg, foo))
{
// ...
}
If you want to default-initialize the base class, you could use the copy-ctor to copy a default initialized base class instance:
Base DoStuffBeforeCtorAndReturnDefaultBase(int arg, Foo foo)
{
DoStuff(arg, foo);
return Base();
}
MyClass::MyClass(int arg, Foo foo)
: Base(DoStuffBeforeCtorAndReturnDefaultBase(arg, foo))
{
// ...
}
Or, if Base doesn't have to be the first base class, you could derive MyClass from a helper class:
MyClass::MyClass(/* ... */)
: DoStuffHelperClass(/* ... */),
Base(/* ... */)
{
// ...
}
All of the above require that the "stuff" you do does not depend on the object that's about to be initialized (i.e. the functions can't safely be member functions and you cannot safely pass this as an argument to them either).
That means you can do some logging or similar, but then again you could also do that after the base class has been initialized.
(EDIT except with the DoStuffHelperClass solution, you can of course have members in DoStuffHelperClass, access them and what not)
Although I have to say that I can't recall ever using/needing/wanting something like that. It's quite probable that there is another (preferable) solution for what you're trying to do.
Use the base-from-member idiom to run your code before the ctor of the "real" base class (which is Base):
struct Base {
Base(string, int);
};
struct DerivedDetail {
DerivedDetail() {
value = compute_some_value();
value += more();
value += etc();
other = even_more_code(value);
}
string value;
int other;
};
struct Derived : private DerivedDetail, Base {
Derived() : Base(value, other) {}
// In particular, note you can still use this->value and just
// ignore that it is from a base, yet this->value is still private
// within Derived.
};
This works even if you don't have actual members you want in DerivedDetail. If you give more specifics on what you must do before the Base's ctor, then I can give a better example.
The base class is always fully constructed before construction of your own class begins. If you need to make a change to the state of the base class, you have to do that explicitly after it has been constructed.
Example:
MyClass::MyClass()
{
// Implicit call to Base::Base()
int result = computeSomething();
Base::setResult(result);
// ...
}
Besides the already written solutions, you can also use a static constructor function and make the contructor of MyClass private.
class QtBase{
// ...
};
class MyClass : public QtBase{
public:
// copy ctor public
MyClass(MyClass const& other);
static MyClass Create(/*args*/){
// do what needs to be done
int idata;
float fdata;
// work with idata and fdata as if they were members of MyClass
return MyClass(idata,fdata); // finally make them members
}
static MyClass* New(/*args*/){
int idata;
float fdata;
// work with idata and fdata as if they were members of MyClass
return new MyClass(idata,fdata); // finally make them members
}
private:
// ctor private
MyClass(int a_idata, float a_fdata)
: idata(a_idata)
, fdata(a_fdata)
{}
int idata;
float fdata;
};
Now you would have to create instances of MyClass either as:
MyClass obj = MyClass::Create(/*args*/);
or
MyClass* ptr = MyClass::New(/*args*/);
no, because it will not be type safe.
consider you have: a class A and a variable A.var.
now consider B inherits from A, and uses var before A was initialized. you will get a run time error! the language wants to prevent this, thus superclass constructor must be initialized first.
No, you can't do it that way, as other have described in their previous answers.
Your only chance is composition, IOW that MyClass uses Base class as a member field:
class MyClass {
public:
/** the methods... */
private:
Base* _base;
};
so you can initialize _base later, when you have the needed info. I don't know if this can apply to your scenario, anyway.
No. It is not possible, because the order of constructor calls is strictly defined by the standard. Base class ctor has to be executed before the derive class ctor can be executed.
i have this :
class A {
public :
A(int i ) : m_S(i)
{
m_Pa = new Foo(*this) ;
}
private :
int m_S ;
Foo* m_Pa;
}
and derived class
class B : public A {
public :
B() : A (242)
{
// here i like to override the A class m_Pa member but i don't know how to do it right
}
}
your m_Pa should be protected than you can call like:
B() : A (242), m_Pa(12)
{
}
or
B() : A (242)
{
m_PA = 55
}
or you should make a public or protected function which changes m_Pa
class A {
public :
A(int i ) : m_S(i)
{
m_Pa = new Foo(*this) ;
}
void setPA(int val)
{
m_PA = val;
}
What is m_Pa? You never had it declared. Assuming it's a private data member of type Foo* in class A, you can't directly change it in the derived class unless you change A's interface. E.g., you can provide a protected setter member function:
class A {
....
protected:
void setFoo(const Foo* foo);
}
class B {
....
Foo *foo = new Foo(this);
setFoo(foo);
}
You can't override member variables in a derived class, only methods.
Short answer: By declaring m_Pa private, you are saying that only class A should be able to modify it. So you cannot alter its value using methods of class B.
Longer answer: In C++ (and most other object oriented programming languages), you not only declare the type of a member, but also its visibility (public, protected and private). This allows you to enfore encapsulation of data: You only expose an interface, but you do not let clients of your class modify its internals directly.
In your concrete example, I would create accessors
Foo* getPa() {
return m_Pa;
}
void setPa(Foo* Pa) {
m_Pa = Pa;
}
in class A and use them in class B to modify m_Pa. If you would like class B (but not unrelated classes) to be able to modify m_Pa declare getPa() and setPa() in a protected: section of your class; if you would like any client to modify them declare them in a public: section. Especially in the later case you need to start worrying about object ownership, i.e. which object is responsible for deleting the object stored in m_Pa which is created in the constructor. A practical solution to this problem is to use smart pointers, see for instance boost's implementation.
A note on terminology: "Overriding" a member in C++ usually refers to giving a new implementation of a virtual member function. So if your class A has a method
virtual void doIt()
then a member of the same type in class B overrides the implementation of A's doIt().