Defining base class member pointer with the adress of derived class member - c++

See example of what I'm talking about in the code below, in class B.
Am I doing something wrong, memory wise ?
I'm having segmentation faults that I didn't have before that...
class Obj
{
};
class ObjDerived : public Obj
{
};
template <typename T>
class A
{
public:
Obj<T> *pObj;
public:
A(Obj<T>* pO) : pObj(pO) {}
void doSomethingWithObj()
{ pObj->print(); }
};
template <typename T>
class B : public A<T>
{
public:
B() : A<T>(&o), o(ObjDerived<T>(1.0)) {}
void doSmthg()
{ (this->pObj)->print(); }
public:
ObjDerived<T> o;
};

I think what you need is to make print() a virtual function in class Obj and override it in class ObjDerived. Then you don't need to mess around with raw pointers which are evil.

I think the main issue that would occur with your code is that in the constructor for B you're passing a variable that you've not yet created to the base class.
B()
: A<T>( &o)
, o( ObjDerived<T>( 1.0f))
{}
In the constructor, the commands are performed in order so you're passing B::o which hasn't been created yet to A::A and THEN creating the B::o variable.
The only solution that comes to mind, if you really want to stick to this class structure would be to make A::pObj a pointer to a pointer so it could then access the new variable by first going to B::o. However that would look horrendously messy in my opinion.
EDIT: As John Smith has said, I think you need to look into using virtual functions and inheritance a bit more to neaten the class structure out.

Related

Initialize Inner Class with outer class this possible?

Today i tried to instanciate an inner class while passing my outer class to it and while i am in the namespace of the outer class:
I'm using Visual Studo 2013.
Code looks like this : (watch the ^^)
class Base
{
public:
virtual void foo(){ cout << "foo" };
};
class object
{
class Derived : public Base
{
object& o;
public:
Derived(object& o) : o(o){}
virtual void foo(){ cout << "bar" };
}derived(*this);
// ^^^^^^
};
The derived class inheriting something does not affect anything for this example here as far as i tested. (only in here for context reasons , see below)
On this ^^ point i recieve error:
no appropriate default constructor available
Intellisense warns me, that it expects type specification.
I also tried passing a pointer (of course i changed construktors then, too)but same reaction.
For protokoll i tried quite a lot of variations and research by now, but i cannot isolate a clear answer to my problem.
Is the "this" pointer not usable here ? How can i pass myself then at this point ?
For Background (only if you're interested):
I tried to write Code for Keybinding in an Application. To pass
functions to the Keys i use an "Interface" of class KeyFunction (Base
class resembles it).
I now want to give classes (object) the possibility to declare it's
own KeyFunction(Derived) and , more important, pass ressources(object)
with it, in a way that functions can work on them (since i can only
use void pointers, because they are later stored in an array for the
bindings) I already achieved this task with other code which i think
is to long to post here, though. By experimenting i stumbled across
this problem.
Your compilation error has nothing to do with your class hierarchy, but with the simple fact that this is not how you go about constructing a class instance.
Try actually declaring a class member, and a class constructor:
class Base
{
public:
virtual void foo(){ }
};
class object
{
class Derived : public Base
{
object& o;
public:
Derived(object& o) : o(o){}
virtual void foo(){ }
};
Derived derived;
object() : derived(*this)
{
}
};

How do I specify a required inheritance for a template class argument?

I have the following structures:
class ElementEx
{
public:
ElementEx() {}
AddChild(ElementEx* element)
{
// some stuff
}
};
class A : ElementEx
{
public:
A() {}
};
class B : ElementEx
{
public:
B() {}
};
template <class T>
class MyNewClass : public T
{
public:
MyNewClass()
{
ElementEx* newElement = new ElementEx();
AddChild(newElement);
}
};
When creating a MyNewClass object, T must inherit from A or B, so MyNewClass will descend from ElementEx. But in my example, the compiler doesn't know this, and can't figure out what AddChild is. How do I make sure the T class is a descendant of ElementEx?
I'm imagining doing
((ElementEx*)this)->AddChild(newElement);
But that seems really inelegant (and prone to error, if the wrong type is fed in as T), and I figure there must be a better way to do this.
The compiler is complaining here because it doesn't know that AddChild is dependent on T during the first pass. AddChild can be made a dependent name by prepending the call with this-> hence delaying the lookup to the second pass when T is known.
As long as you're content that the parent class supports AddChild accepting an ElementEx you can do this easily using the normal compiler error.
After fixing a bunch of errors in your code (A and B inherit privately, all your classes have private constructors, AddChild has no return type) I was able to make it work fine by adding this-> to the call to AddChild because AddChild is a dependent name and you indicate that to the compiler by either qualifying the type or by adding this->. If you don't anticipate the need for virtual calls to that method you could altenately call ElementEx::AddChild to force the correct lookup. Corrected code follows.
class ElementEx
{
public:
ElementEx() {}
void AddChild(ElementEx* element)
{
// some stuff
}
};
class A : public ElementEx
{
public:
A() {}
};
class B : public ElementEx
{
public:
B() {}
};
template <class T>
class MyNewClass : public T
{
public:
MyNewClass()
{
ElementEx* newElement = new ElementEx();
this->AddChild(newElement);
}
};
struct Bad {};
int main()
{
MyNewClass<B> b; // Compiles.
MyNewClass<Bad> bad; // error: 'class MyNewClass<Bad>' has no member named 'AddChild'
}
There are a few ways to do this nicely, but they all have the basis of using 1.) static assert. 2) Static eval functions.
Personaly, I'd use (in the constructor)
static_assert(std::is_base_of<ElementEx,T>::value,"T must derive from ElementEx")
But there is probably a better way. What is the X part of your problem (what are you trying to achieve with this weird inheritance structure?)

How to make abstraction for Base class using virtual functions?

I have the following structure
class Base
{
public:
Base(Type);
virtual render
}
class A
{
public:
Base(Type == A);
void render()
}
class B
{
public:
Base(Type == B);
void render()
}
void client_function()
{
Base baseObject(A);
//Base is an instance of class A
baseObject.render()//runs class A render
}
There are things in the above code that are not c++ as far as I am aware, they are closely related to pattern matching found in Haskell for example, but this is the best way I could find to illustrate my question without already knowing the answer ;)
In writing I want the client to be able to create a base object and pass the type of object as an argument, the correct specification of the object is returned and the client need not care less about it, just knows that running render will run the correct specific render.
Please feel free to ask questions if I have been unclear :)
I think you need to read about virtual functions and inheritance:
http://www.parashift.com/c++-faq-lite/virtual-functions.html
http://www.parashift.com/c++-faq-lite/proper-inheritance.html
http://www.parashift.com/c++-faq-lite/abcs.html
You need run-time polymorphism. There is not much important part of constructor. You have to inherit the Base into A and B. For example:
class Base
{
public:
virtual void render (); // <--- declare 'virtual'
virtual ~Base(); // <--- very much needed to avoid undefined behavior
};
class A : public Base //<---- inheritance
{
public:
void render(); // <--- this also becomes 'virtual'
};
...
Now you can use as per your requirement.
Base *baseObject = new A(); // <----- need to use pointer (or reference)
(*baseObject).render(); // <--- other way to write: baseObject->render();
delete baseObject;
I'm not sure I understood your question. In C++ you cannot choose your base class at runtime, but you certainly can have your base class depend from the derived class. This is done by using templates and what is known as the Curiously Recurring Template Pattern:
template <typename T> class Base {
public:
virtual void render(T *) {}
};
class A : public Base<A>
{
public:
void render(A * t) {}
};
class B : public Base<B>
{
public:
void render(B * t) {}
};
void client_function() {
A a1;
A a2;
a1.render(&a2); // calls A::render
a1.Base<A>::render(&a2); // calls Base<A>::render
Base<A> * ba = &a1;
ba->render(&a2); // calls A::render
}
Hope this answers your question.
What you ask for is exactly what inheritance is for: creating object from a class hierarchy that specializes a functionality.
In your example, apart from syntax problems, things will work as you expect, i.e. method A::render will be called, even if you don't know at compile time that object, declared as a Base, is indeed a A. That's virtual inheritance magicness.

Redefine a derived class' variable

Is the following valid? Or how can I get something close to this.
template<class T_> class Template {
//something
};
class Parent {
public:
Template<Parent> variable;
Parent() : variable(this) { }
};
class Derived : public Parent {
public:
Template<Derived> variable;
Derived() : Parent() { }
}
Thanks in advance.
It's technically "valid" in that your compiler has to accept it (it may warn you, and IMHO it should), but it doesn't do what you think it does: Derived's variable is separate from Parent's, and is not getting explicitly initialized (so it uses the default ctor for Template<>).
If you want to have a variable with the same name in a base and derived class you don't need templates.
Just define them and from derived access ->variable and ->Base::variable. Those are 2 different variables.
Few minor types.
But the main problem was that Parent was using a constructor on Template that did not exist.
template<class T>
class Template
{
public:
Template() {} // Used in Derived
Template(T* t) {} // Used in Parent
};
class Parent
{
public:
Template<Parent> variable;
Parent() : variable(this) {}
};
class Derived : public Parent
{
public:
Template<Derived> variable;
Derived() : Parent() {}
};
I am curious what you are trying to achieve though.
Is this some variation of the "Curiously Reoccurring Template" Pattern or something?
You shouldn't get something close to this, because such a redefinition of a public variable violates Liskov Substitution Principle - your Derived becomes more restrictive than Parent, and cannot be substituted in its place, and therefore it shouldn't be in a superclass/subclass relation.
Furthermore, if it would allow you to redefine a field in a sense of actually reusing the same memory location somehow, then it would break the type system as well: all methods in Parent expect variable to be of type Template<Parent>; if it actually be an instance of Template<Derived>, there is no guarantee that Template<T> is covariant in T.

C++: Design, Function template overriding and lack of polymorphism

Have a base class A, and a derived class B which overrides function template Func:
class A
{
A() {...};
~A() {};
template <class T>
void Func(const String &sInput, T &tResult)
{...}
};
class B : public A
{
B() {...}
~B() {};
template <class T>
void Func(const String &sInput, T &tResult)
{...}
};
(Note that Func is non-virtual, given the lack of support in C++ for templated virtual functions.)
Now have a mainprog API, class M:
class M
{
M(boost::shared_ptr<A> &pInterfaceInput): pInterface(pInterfaceInput)
{}
template <class T>
Evaluate(const String &sInput, T &tResult)
{
pInterface->Func<T>(sInput, tResult);
}
private:
const boost::shared_ptr<A> pInterface;
};
I want the function Evaluate here to support calls to functions on base class A or any of its derived classes (such as B). This class was written with polymorphism in mind before I re-designed class A and B to have templated functions.
Now the problem here is that if I pass a shared pointer of the base type to the derived type then Func of the base class will be called, not the derived class being pointed to.
How do I get around the lack of dynamic polymorphism here?
I've considered making class M a class template on the shared pointer type and having a static_cast in the constructor to ensure this type is of the base class type (A) or of a derived class.
What's the nicest way to do this? I'd prefer not to modify classes A and B to get around this problem but all suggestions are welcome.
Thanks.
Sounds like a double dispatch problem. Perhaps this would be a good place to implement the visitor pattern?
For example, create a class Evaluator, and for each T a subclass ConcreteEvaluator<T>. Give A and B methods that visit the Evaluator. Something like:
class Evaluator
{
virtual void visit_A(A* object);
virtual void visit_B(B* object);
};
template <typename T>
class ConcreteEvaluator : public Evaluator
{
public:
String* input_reference;
T& result_reference;
ConcreteEvaluator(String& input_reference_,T& result_reference_) :
input_reference(input_reference_),
result_reference(result_reference_) {}
virtual void visit_A(A* object) {
object->Func(input_reference,result_reference);
}
virtual void visit_B(B* object) {
object->Func(input_reference,result_reference);
}
}
class A
{
...
virtual void apply_evaluator(Evaluator *eval) {eval->visit_A(this);}
...
}
class B
{
...
virtual void apply_evaluator(Evaluator *eval) {eval->visit_B(this);}
...
}
For each subclass of A, a new method must be added to ConcreteEvaluator, so that this technique works best if A's class hierarchy is stable. And for each subclass of A, it must have an apply_evaluator function defined properly.
On the other hand, this may be total overkill. For about the same amount of work, you could always just pay the price to update M::Evaluate:
class M
{
...
void Evaluate(const String& sInput, T& tResult)
{
// try to downcast to each subclass of A. Be sure to check
// sub-subclasses first
try
{
dynamic_cast<B*>(pInterface.get())->Func(sInput, tResult);
return;
}
catch (std::bad_cast& ) { }
...
// nothing worked. It must really be an A
pInterface->Func(sInput,tResult);
}
...
};
I've show in the question Templatized Virtual function how to use type erasure to get some of the effects of virtual member function. Depending on what you want to do in Func(), you can use the same technique here.