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)
{
}
};
Related
I have three classes:
Class Something
{...}
Class A
{
public:
A();
virtual ~A() = 0; //have also tried this as non-abstract
std::vector< unique_ptr<Something> > somethings; //have tried this just as std::vector<Something*> as well
};
class B : public A
{
B();
...
}
if I leave out the declaration of std::vector< Something* > somethings, from class B... then my compiler tells me that class class ‘B’ does not have any field named ‘somethings’.
So if I add it back in, and I try to reference it like so
A *a = new B();
for(auto it = a->somethings.begin(); it != a->somethings.end(); it++)
{
Draw((*it)->image,(*it)->x, (*it)->y, NULL, (*it)->angle);
}
It says that a->somethings is empty... even though if I print from B itself to tell me how many 'somethings' there are, it is accurately reporting the count. This is what led me to remove std::vector< unique_ptr > somethings; from class B to begin with, as I suspected it was somehow getting A's vector instead, even though it's abstract.
Bonus: This all works if I go B *b = new B(); just broke when I added the parent class A and made B inherit from it.
From the linked code in your comment, the problem is that you're trying to initialize the base class field directly in the derived class. You can't do that (and it makes no sense to try) as the base class fields are initialized by the base class constructor. If you want to initialize the field (rather than assigning to it), you need to do it in the base class constructor:
class Base {
public:
std::vector<float> fVec;
Base(std::vector<float> v) : fVec(v) { }
};
class Derived : public Base {
public:
Derived(std::vector<float> v) : Base(v) {
:
Note that the code you show above is completely different from and unrelated to what you linked to -- you should post the code that pertains to your question, and not unrelated irrelevant code.
I'm not sure if this will help you, but I made a small change to your coliru.stacked-crooked example as follows:
#include <vector>
class Base
{
public:
std::vector<float> fVec;
};
class Derived : public Base
{
public:
Derived(std::vector<float> v) // : fVec(v)
{
fVec = v;
}
};
int main() {}
Notice I commented out the fVec from the constructor initialisation list and assigned it in the body of the constructor. The problem here is that your Base object hasn't been created fully until you enter the opening brace of the body of your Derived constructor.
To work around this issue, you could add a constructor to your Base object that takes a vector and then assign that to your object, more or less what Chris said.
Both examples above work for me, but I don't have your full code so can't be sure they'll fix all your problems. I thought I'd take a punt anyway.
You probably know all about the copies of vectors being made and should be passing them as const refs, but that's another issue.
I have a base class with a bunch of functionality and a derived class that extends that class but there are a few methods in the base class that don't make sense on the derived class.
Is it possible to do something to prevent these method(s) from being used by the derived class?
Class A
{
...
public:
void SharedMethod();
virtual void OnlyMakesSenseOnA();
}
Class B : public Class A
{
...
public:
void OnlyMakesSenseOnB();
}
The following obviously doesn't work but is it possible to do something similar so that the compiler doesn't allow a certain base class method to be called?
Class B : public Class A
{
...
public:
void OnlyMakesSenseOnA() = 0;
}
No, and this is completely wrong. If the member function is not callable in the derived type you are breaking the Liskov Substitution Principle. Consider whether this is the correct inheritance relationship. Maybe you want to extract SharedMethod to a real base and provide two separate unrelated A and B types.
This isn't as easy of an answer as I had hoped, but a coworker suggested that this situation is an indication of bad design and that I should re-think my inheritance structure by adding a new base class that only contains common functionality:
Class Base
{
...
public:
void SharedMethod();
}
Class A : public Base
{
...
public:
void OnlyMakesSenseOnA();
}
Class B : public Base
{
...
public:
void OnlyMakesSenseOnB();
}
Edit: Thanks to #David for providing a name for the rule that I'm trying to break. B is not a "Behavioural Subtype" of A because it fails the "counterfeit test". Therefore, deriving B from A violates the Liskov Subtitution Principle.
According to this slide deck, the counterfeit test is as follows:
Suppose I promise to deliver you an object of class T, but
instead I give you an object x of class S.
You can subject x to any series of method calls you like
(chosen from T’s signature).
If x behaves in a way that is not expected of a T object,
then you know it is a counterfeit, x has failed the test.
If all S objects always pass every counterfeit test, then S is
a behavioural subtype of T.
You could also just throw an exception if the invalid method is called on the derived class. It doesn't catch the bug at compile time but at least it prevents it from accidentally being used a runtime.
Class B : public Base
{
...
public:
void OnlyMakesSenseOnA() { throw Exception(); }
}
Yes, it's possible and quite simple, if we're talking about an external call. You can hide parent's method with private methods of derived class. Works with the static methods as well.
Tested on cpp 98, 11, 14. Try yourself in C++ shell.
class Base{
public:
void methodBase(){};
static void methodBaseStatic(){};
};
class Derived : public Base{
//private: //(private on default)
void methodBase(){};
static void methodBaseStatic(){};
};
Normal operation:
int main()
{
Base b;
b.methodBase();
Base::methodBaseStatic();
Derived d;
return 0;
}
Compilation error
int main()
{
Derived d;
d.methodBase();
Derived::methodBaseStatic();
return 0;
}
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.
How can I print out the derived class name from the base class without chaining constructors all the way down. In other words is it possible to do this strictly from the base class without adding code in each derived class?
This is an example of what I got, and if there's a way I'd like to get rid of the constructor chaining.
EDIT:
Ideally I am looking for something to add into the base class without having to edit all derived classes. At the moment my real code has got ~17 classes(with need for more), so something that could do the job straight from the base class would be ideal. Even if it's compiler specific (g++ or clang).
#include <iostream>
class Base {
public:
Base(std::string id) {
std::cout<<"Creating "<<id<<std::endl;
}
};
class Child : Base {
public:
Child(std::string id) : Base(id) {}
Child() : Base(typeid(this).name()) {}
};
class GrandChild : Child {
public:
GrandChild(std::string id) : Child(id) {}
GrandChild() : Child(typeid(this).name()) {}
};
class GrandGrandChild : GrandChild {
public:
GrandGrandChild(std::string id) : GrandChild(id) {}
GrandGrandChild() : GrandChild(typeid(this).name()) {}
};
int main() {
GrandGrandChild *A = new GrandGrandChild();
GrandChild *B = new GrandChild();
Child *C = new Child();
return 0;
}
Which prints:
Creating GrandGrandChild
Creating GrandChild
Creating Child
But with compiled added prefix.
There is unfortunately no easy solution.
The problem is that constructing polymorphic objects is quite complicated, at the moment you are building the Base subpart of a Child class, you are building a Base still, not a Child (because trying to access Child members would be non-sensical, they have not been built yet!)
As such, all the ways to retrieve dynamic information (known as RTTI or RunTime Type Information) are voluntarily locked down to prevent such mistake.
For symmetrical reasons, the same occur in the destructor.
Now, only the constructor and destructor are so locked down, therefore you can perfectly have a name() method that will happily return the true name of the dynamic type of the instance in all other cases:
class Base {
public:
std::string name() const { return typeid(*this).name(); }
};
It will work... unless you invoke it from a constructor or destructor in which case it will report the static type.
Now, as far as the "bizarre" output, each implementation (compiler) is allowed to provide its own output here (and they need not even be different for different types, crazy eh!). You seem to be using gcc or clang.
There are demanglers to interpret such output, or if your program is simple enough and their interface scares you, you might simply try to parse it manually to remove the cruft. The name of the class should appear fully, it'll just be preceded with some nonsense (namespaces and numbers essentially).
you can provide an initialization function that needs to be called from each constructor.
class Base {
protected:
Base() { init(typeid(this).name()); }
void init(std::string id) {
std::cout<<"Creating "<<id<<std::endl;
}
};
You somehow need to make sure, that subsequent inits will safely supersede the changes of previous ones:
Creating P4Base
Creating P5Child
Creating P10GrandChild
Creating P15GrandGrandChild
Creating P4Base
Creating P5Child
Creating P10GrandChild
Creating P4Base
Creating P5Child
I intend to use it purely for debugging purposes, which is why something to throw into the base class would be convenient.
have you considered adding a macro to your code to print the debug output?
#ifdef DEBUG
#define PRINT_CLASSNAME std::cout<<"Creating "<<id<<std::endl;
#else
#define PRINT_CLASSNAME ;
#endif
You need to add it to your constructors once, but if you want to disable it (temporarily) you just undefine it?
Since you indicate this is for debugging, you can rely on virtual inheritance to avoid passing the name through all the intermediate derived classes, and instead pass it directly to the Base. Also, Base can be modified to take a template constructor to simplify things for the derived classes.
class Base {
public:
template <typename DERIVED>
Base (DERIVED *d) {
std::cout << "Creating " << typeid(*d).name() << std::endl;
}
};
class Child : virtual public Base {
public:
Child () : Base(this) {}
};
class GrandChild : public Child, virtual public Base {
GrandChild () : Base(this) {}
}
class GrandGrandChild : public GrandChild, virtual public Base {
GrandGrandChild () : Base(this) {}
}
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.