I can't think of a better title... please edit if you can!
class AbstractGUIBase
{
...
};
class GUIConcrete : public AbstractGUIBase
{
...
};
class AbstractApplicationBase
{
AbstractGUIBase *mGUI;
};
class MyApplication : public AbstractApplicationBase
{
GUIConcrete *mGUI;
};
This is basically the setup I have... an application base-class provides common functionality including a reference to a GUI base-class instance mGUI. mGUI is only ever instantiated in MyApplication or other concrete sub-classes.
I don't want to re-declare mGUI in both classes because I end up doing something like super::mGUI = mGUI = new ConcreteGUI(). But I also don't want to have to cast mGUI every time it's used in MyApplication.
Is there a normal patter here? I was thinking you could template AbstractApplicationBase on the GUI class type but I don't especially like template programming.
I'm using MSVC++2008 so no fancy modern stuff is available.
I'll try to strip away the details of your model and focus on the following abstract design:
struct A struct DA : A
{ {
}; };
//==============================================================================
struct B struct DB : B
{ {
A* p; DA* pD; // Avoid this
}; };
Now what you are trying to do is to avoid adding an extra member variable to DB, and be able to treat the pointer p inherited from B as if it were of type DA*.
You can structure classes B and DB this way:
struct B
{
private:
A* p;
public:
B(A* _p) : p(_p) { }
A* get_p() { return p; }
}
struct DB : B
{
public:
B(DA* _p) : B(_p) { }
DA* get_p() { return static_cast<DA*>(A::get_p()); }
}
Superclass B will hold a pointer of type A*. This pointer is set at construction time. If the constructor is invoked while creating an instance of DB, a pointer to an object of type DA will be stored. DB provides a function get_p() that hides B's version of get_p() and returns a (properly casted) pointer of type DA*.
Due to this design, the static_cast<> in DB::get_p() is guaranteed to be safe (unless you use virtual inheritance, in which case you should use the less efficient dynamic_cast<>).
Internal operations of B would access the pointer p directly. Clients of B would retrieve it through a call to B::get_p(). Inside of DB, and for clients of DB as well, you would access the object pointed to by p by retrieving the pointer through function B::get_p(), rather than directly dereferencing p.
Related
I have one base class and two derived child's (different classes).
I would like to construct one child and then construct a second child which uses the same base class instance like the first child.
In pseudo code this would look like this:
class Parent
{
public:
int x;
};
class ChildA : public Parent
{
void setX() {x=5;}
};
class ChildB : public Parent
{
int getX() {return x;} //Shall return 5 after calling the set method of ChildA first
};
//Creating instances
ChildA* a;
a = new ChildA();
Parent* ptrToBaseClass = a;
ChildB* b;
b = new ChildB(); //How can I set this to the same base class ptr (Parent*) which instance “a” has?
How can this be achieved with passing the base class pointer?
I would like to construct one child and then construct a second child which uses the same base class instance like the first child.
What you would like is not possible. Each base class sub object is stored within the most derived object.
You can use the existing base to copy initialise the base of another object, but they will be separate.
What you could do to achieve something similar, is to use indirection:
struct Parent
{
std::shared_ptr<int> x = std::make_shared<int>();
};
struct ChildA : Parent
{
void setX() {*x=5;}
};
struct ChildB : Parent
{
int getX() {return *x;} //Shall return 5 after calling the set method of ChildA first
};
int main() {
ChildA a;
Parent& a_base = a;
ChildB b {a_base}; // note that the base is copied here
a.setX();
std::cout << b.getX();
}
This way even though the base objects are separate, they both refer to shared state.
A simpler solution is to store the state in static storage (such as static member, as suggested by Ahmet). But this will make the state shared across all instances while the indirection allows exact control over which objects share which state.
You can make the x in Parent class static. This will allow you to do this - although I have to warn you that this is quite a dodgy code and can bite you in the a**.
Of course, then you have to access it with rather than just x; as Parent::x.
EDIT: I seem to got it wrong. If you want the whole base class as 'shared' rather than just x; you need pointers and custom logic to manage it - there is no direct language construct.
Referencing this question: C++ virtual function return type
Let's consider the following set of objects.
class ReturnTypeBase
{
};
class ReturnTypeDerived1 : public ReturnTypeBase
{
public:
int x;
};
class ReturnTypeDerived2 : public ReturnTypeBase
{
public:
float y;
};
class Base
{
public:
virtual ReturnTypeBase* Get() = 0;
};
class Derived1: public Base
{
public:
virtual ReturnTypeDerived1* Get()
{
return new ReturnTypeDerived1();
}
};
class Derived2: public Base
{
public:
virtual ReturnTypeDerived2* Get()
{
return new ReturnTypeDerived2();
}
};
Can these objects be used in the following way?
Base* objects[2];
objects[0] = new Derived1();
objects[1] = new Derived2();
ReturnTypeDerived1* one = objects[0]->Get();
ReturnTypeDerived2* two = objects[1]->Get();
I'm assuming since the return types are covariant(?), that the set of objects above is legal C++. Will the appropriate Get() method be called? Can the pointers one/two be assigned the return value of the Get() method without casting?
The code will not compile as written. Because objects[0] has static type Base*, invoking the Get function results in a pointer with static type ReturnTypeBase* being returned. Since this is an overridden virtual function, the derived class's Get function will be called as you would expect, and the returned pointer would actually point to a ReturnTypeDerived1 object, but the compiler can't prove this. You would need a cast:
auto one = static_cast<ReturnTypeDerived1*>(objects[0]->Get());
auto two = static_cast<ReturnTypeDerived2*>(objects[1]->Get());
If you make ReturnTypeBase a polymorphic type, you can use dynamic_cast here instead to avoid undefined behaviour if you happen to be wrong about the dynamic type.
As written, you will get compiler errors on the .Get() call.
If you want to avoid that, make the assignment to base class..
ReturnTypeBase * one = objects[0].Get();
ReturnTypeBase * two = objects[1].Get();
As long as you access 'one' and 'two' through abstract methods defined in the base class, (eg. a 'toString()' method), you won't have problems with the internal data.
If you intend on treating the data the same across all instances of the base class, you might want to considering using a template class instead.
I have a base class and several derived classes. The base class looks like this:
class Base
{
int type; //the derived type the object belongs to
int nOfChildren;
Base** children; //each child can be any of the derived types
...
}
Now I need to duplicate an instance of Base. Because of the recursion, a virtual method Base::duplicate() is needed. It also seems clear what should go in it:
Base temp = new Base();
temp->type = temp;
temp->nOfChildren = nOfChildren;
temp->children = new Base*[nOfChildren];
beyond that, it's not so clear.
Do I allocate each temp->children[i] as a Base object or as a derived object? Do I need a case statement to cater to all possible derived types? Do I need to implement a duplicate() method for each derived type, even those that contain no other information than the Base class? (If a derived class contains more information, then it is clear that I need a separate mechanism. There are several derived classes that contain no further data than the base, although they contain different implementations of a handler() method not shown.)
You are right, a virtual method is needed for cloning the polymorphic object. OTOH, you can leverage C++ features to simplify writing it:
class Child : public ICloneable {
public:
// stuff...
Child *clone() const { return new Child(*this); }
}
Also, don't put collections of objects into arrays! Use std::vector instead.
class Base
{
// stuff...
std::vector<Base*> children;
}
Even better, use a smart pointer to wrap the cloning operation into an object std::vector will be able to manage transparently.
template<typename T>
struct clone_ptr {
T *object;
clone_ptr() : object(new T()) {}
clone_ptr(T *object_) : object(object_) {}
clone_ptr(clone_ptr<T> const &other) : object(other.object->clone()) {}
clone_ptr<T> &operator=(clone_ptr<T> other) {
std::swap(object, other.object);
return *this;
}
~clone_ptr() { delete object; }
};
That way you can just use a std::vector of clone_ptrs into your Base:
class Base
{
// stuff...
std::vector<clone_ptr<Base>> children;
}
Each object will be automagically copied into an object of the same polymorphic type, as long as you implement clone() in each class. The vector will be cloned in the same way other data members are, automatically by the C++ compiler.
Is it an O.K. design if i return an instance of Derived class from Base class member function(created using new Derived()) ?
Also this involves the need to forward declare the Derived class and also make the Derived class constructor public.
Code Sample :-
Class Base
{
public:
Base() {}
Derived* get_new_derived(int X)
{
Derived *der = new Derived(X);
return der;
}
}
Class Derived : public Base
{
private:
int _X;
protected:
Derived(int X) { _X = X; }
public:
Derived* get_new_derived(int X)
{
Derived *der = new Derived(X);
return der;
}
}
I have one more derived class(say Derived1). Now let's say :-
Usage1 :
Derived1* der1 = new Derived1();
Derived * der = der1->get_new_derived(10);
Usage2 :
Derived1* der1 = new Derived1();
Base* bs = der1;
Derived * der = bs->get_new_derived(10);
In the general case, this usually indicates bad design - a base class shouldn't normally know/care about its derived classes.
Note that you can return a pointer to Derived typed as Base* - that's the principle of the Factory Method design pattern. Perhaps this fits your actual scenario?
Note however that all rules have exceptions. If your (base class + derived classes) represent a tighly coupled and coherent unit (such as a Tree interface with two subclasses FastTree and SmallTree, optimised for different purposes), it is acceptable for them to be aware of each other, and Tree defining such functions as:
std::unique_ptr<SmallTree> Tree::createSmallCopy() const
{
return { new SmallTree(/*args*/) };
}
std::unique_ptr<FastTree> Tree::createFastCopy() const
{
return { new FastTree(/*args*/) };
}
So it depends on your actual use case. I'd generally be wary of such design, it but it has its uses.
As a side note, in modern C++, you should never use an owning raw pointer - use a smart pointer like std::unique_ptr or boost::shared_ptr.
How about this?
// The Curiously Recurring Template Pattern (CRTP)
template<class Derived>
class Base
{
// methods within Base can use template to access members of Derived
};
class Derived : public Base<Derived>
{
// ...
};
http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
Yes you can do it. The question is whether you should.
You shouldn't do it since it implies Base knows Derived which isn't proper object oriented design. The dependencies should be one way - derived knows the Base and not vice versa.
I have two classes in a class hierarchy where a parent class needs to have an instance of a class derived from it as a member variable. As an example:
class B;
class A {
public:
B* binst;
A();
};
class B : public A {
};
A::A() {
binst = new B;
}
Obviously, this causes an infinite recursion in the constructors, because to create a new B you have to call A's constructor, which creates a new B which calls A's constructor, and so ad infinitum.
Is there a way around this? The problem I'm having in this is that A has to have a B in it, but B must be derived from A, and there's not a way to prevent that.
To get an idea of why I need to do this, consider an object oriented hierarchy for a scripting language (like python or ruby or lua, etc):
All instances of anything are derived from a base class, Object.
Object has a method lookup table, which is an instance of MethodTable.
MethodTable is derived from Object, and must be, for the scripting language to be able to operate on it.
"Object has a method lookup table"
"MethodTable is derived from Object"
Putting aside coding concerns, do these statements really make sense together from even a conceptual standpoint? Should a MethodTable have its own MethodTable which then has its own MethodTable... etc?
I'd say it sounds like you need to refactor your concepts a bit. For instance, perhaps Object itself should somehow be responsible for exposing the necessary pieces of its MethodTable member. Thus not requiring MethodTable itself to be an Object. (There may be various other feasible designs too. It's hard to say without deeper knowledge of the actual project.)
Edit: Typically, compiler/implementation-internal types don't derive from language-dependent types. If you look at the internals of Java, their inheritance implementation won't derive from Object. Object is a language construction, it's part of your language's interface. A method table is part of the implementation. A method table should not be operated on by the language, it should be operated on by the implementation.
Moreover, enforced deriving from Object is a stupid thing to do and it happens because you didn't consider the language design and how the users were going to write generic code properly. This is especially true in dynamically typed languages like Lua or Python.
Object could have a private MethodTableImpl member and a public getter that returns a MethodTable. MethodTable contains a MethodTableImpl and derives from Object.
I don't know the purpose of your classes but here is a suggestion :
class A
{
public:
virtual void func DoIt () = 0;
...
};
class B : public virtual A
{
public:
};
class C : public virtual A ,B
{
void func DoIt () { /* statements */ }
};
now there is only 1 instance of class A.
It would be helpful to understand exactly are you trying to achieve via this construct.
As you've noted yourself, this is effectively like having A's constructor construct an instance of A, and that's an unavoidable path to stack overflow.
A more general solution would be to provide a set_subclass method for a pointer to an instance of A, which could then be populated by any subclass of A, not just B.
class A {
public:
A();
virtual ~A();
set_subclass(A* sub) { subclass = sub; }
private:
A* subclass;
};
// List(1) or Stream(2) using inheritance
struct B;
struct A {
B *inst;
A(B *inst_) : inst(inst_) {}
A() : inst(0) {}
};
struct B : A {
B(B *_inst) : A(inst) {}
// chose option 1 or 2
B() : A() {} // option 1: List
B() : A(0) {} // same as above
B() : A(this) {} // option 2: Stream
};
auto B3 = new B(new B( new B));
// This is either a length 3 list (1)
// or a stream (2) implemented by self ref 3rd element
You can make a constructor for class A which accepts a pointer to an object to class B and assign this pointer instead of allocating a new B:
A::A(B* b) : binst (b) {}
And in the construct of class B you pass 'this' in constructor of A:
B::B() : A(this) {}
The compiler will probably complain about it, but you can try. (It is ugly, though.)
Note that you can NOT use the binst pointer to access object B in A's constructor, because it's not fully constructed yet.
Does it actually need the binst as a member, or does it simply need to access it?
class B;
class A {
public:
B& binst(); //throws exception if not derived from B
A() {}
virtual ~A() {} //effectively required for the dynamic_cast
void foo();
};
class B : public A {
public:
void bar() {};
};
B& A::binst() {return dynamic_cast<B&>(this);}
void A::foo() {return binst().bar();}