I have three classes:
BaseClass, that contains ElementClass as field
ElementClass, that contains BaseClass as field and ChildClass as return type (pointer)
ChildClass, that's inherits from BaseClass.
When I'm trying to compile this, I am getting
expected class-name before '{' token
for ChildClass, that was included in ElementClass, that was included in BaseClass.
I understand, why is this happens. Because I'm trying to inherit child class from nonexistent, for compiler, class BaseClass.
I can't understand hot to fix this. Thank you.
Here is code example with this problem
BaseClass.h
#ifndef INHERITTEST_BASECLASS_H
#define INHERITTEST_BASECLASS_H
#include "ElementClass.h"
class ElementClass;
class BaseClass
{
private:
ElementClass *m_someField;
};
#endif
ElementClass.h
#ifndef INHERITTEST_ELEMENTCLASS_H
#define INHERITTEST_ELEMENTCLASS_H
#include "ChildClass.h"
class ChildClass;
class ElementClass
{
private:
ChildClass *m_class;
};
#endif
ChildClass.h
#ifndef INHERITTEST_CHILDCLASS_H
#define INHERITTEST_CHILDCLASS_H
#include "BaseClass.h"
class ChildClass : public BaseClass
{
};
#endif
BaseClass, that contains ElementClass as field
ElementClass, that contains BaseClass as field
So, a BaseClass instance contains an ElementClass instance which contains a BaseClass instance which contains an ElementClass instance which contains... instances all the way down. One instance is going to use all of your memory and then some. That cannot work.
It also cannot work because when defining the first class, you need to have a complete definition of the second class, which needs a complete definition of the first class, which wasn't defined yet.
You must use indirection. At least one of the classes must not contain the other instance inside, but instead a pointer or a reference to an instance.
Related
I am going through some code,plan to adapt it for my research.So header file looks like this
#ifndef SPECTRALCLUSTERING_H_
#define SPECTRALCLUSTERING_H_
#include <vector>
#include <eigen3/Eigen/Core>
class SpectralClustering {
public:
SpectralClustering(Eigen::MatrixXd& data, int numDims);
virtual ~SpectralClustering();
std::vector<std::vector<int> > clusterRotate();
std::vector<std::vector<int> > clusterKmeans(int numClusters);
int getNumClusters();
protected:
int mNumDims;
Eigen::MatrixXd mEigenVectors;
int mNumClusters;
};
#endif /* SPECTRALCLUSTERING_H_ */
Latter in the main code
#include "SpectralClustering.h"
#include <eigen3/Eigen/QR>
SpectralClustering::SpectralClustering(Eigen::MatrixXd& data, int numDims):
mNumDims(numDims),
mNumClusters(0)
So I do not understand why virtual destructor was used in the .h file. From this we can learn that virtual destructors are useful when you can delete an instance of a derived class through a pointer to base class.But I think this is not case with this code.Can someone explain all this?
The reason you would make a destructor virtual is that you plan for that class to be inherited and used polymorphicly. If we had
class Foo {};
class Bar : public Foo {};
Foo * f = new Bar();
delete f; // f's destructor is called here
The destructor for Foo would be called and no members of the Bar part of the object would be destroyed. If Foo had a virtual destructor then a vtable lookup would happen the the Bar destructor would be called instead correctly destroying the object.
It is supposed that the class can be inherited. Otherwise it should be declared with specifier final.
Take into account that data members of the class have access control specifier protected. It means that the author of the class does not exclude that the class can be inherited.
The code was probably written in such a way, that customizing the class implementations by deriving custom classes is supported.
The user of the framework can customize the framework in that way without the need to change the framework code directly. So, probably there is a way to use your derived class in stead of the original SpectralClustering class, or even in stead of any class SpectralClustering derives from (not in this case, as it does not derive from anything). The framework may very well be deleting instances using base class references, while the actual implementation is derived.
for example. We have class A and its derived class; class B. Is it possible to instantiate a pointer of type B in class A?
#ifndef WARRIOR_H
#define WARRIOR_H
#include "CharacterPlayer.h"
class Warrior: public CharacterPlayer
{
public:
virtual void printCharacterName();
};
#endif
however, when i try to instantiate a Warrior pointer or try to include "Warrior.h", it gives me a number of syntax errors.
#ifndef CHARACTERPLAYER_H
#define CHARACTERPLAYER_H
#include "Warrior.h"
class CharacterPlayer
{
public:
Warrior *warriorPntr = nullptr;
virtual void printCharacterName();
};
#endif
You have a circular dependency among your headers: "CharacterPlayer.h" includes "Warrior.h", and "Warrior.h" includes "CharacterPlayer.h". This cannot compile, because the "sentinel" will stop inclusion.
The trick is to forward-declare the Warrior class in the CharacterPlayer instead of including a header:
#ifndef CHARACTERPLAYER_H
#define CHARACTERPLAYER_H
class Warrior; // <<== Here
class CharacterPlayer
{
public:
Warrior *warriorPntr = nullptr;
virtual void printCharacterName();
};
#endif
This is good enough to declare pointers and references to Warrior, but not enough to call methods or instantiate the class.
You need to eventually include the header for Warrior in the cpp file CharacterPlayer.cpp, but that would not lead to any issues, because there is no circular dependency among your headers.
You can, but it's not a good idea.
To do it, simply remove the "#include "Warrior.h" from your second header, and replace it with a declaration of the form "class Warrior;"
As to why it is a bad idea: making a base class contain a pointer to (or an instance of) a derived class is one way (of several) that ensures implementation of the base class depends on implementation of the derived class. Generally speaking, the definition of derived class should depend on the base class, not the reverse, in order to avoid circular dependencies, to allow the base class to be used polymorphically (look up "Liskov Substitution Principle), etc etc.
This means, although it can be done, your design is fundamentally flawed. It would prevent you doing other useful things in future.
I have a Base class which inherits a class with an empty constructor and i then have another class which inherits a class with an empty constructor but i also want this class to inherit my base class but i keep geting errors my code is below
BmvMessage - Base class
BmvMessage inherits - DboGenBmvMessage
BmvMessageStructure inherits - DboGenBmvMessageStruture
I also want BmvMessageStructure to inherit BmvMessage
HPP
class BmvMessage : public DboGenBmvMessage
{
// code
};
HPP OF CLASS THAT I WANT TO INHERIT WITH
class BmvMessageStructure : public DboGenBmvMessageStructure , public BmvMessage
{
//CODE
};
CPP OF THIS CLASS
BmvMessageStructure::BmvMessageStructure() : DboGenBmvMessageStructure(), BmvMessage()
{
}
Without error information it is hard to figure out the issue. First thing that springs to mind is, do you have a terminating ; on your class definition?
class BmvMessage : public DboGenBmvMessage
{
// code
}; // <-
Otherwise perhaps it is an order of declaration issue - are you #include-ing your base classes in the correct order and are they correctly defined?
You are sure you have all the required headers included before inheriting? Line in which error occurs would be nice.
I have already seen a post about the error but This is some what different. So please donot close this. I have an Interface class and I have a class that inherits the interface class and overides the methods in Interface class. The code looks likes this
//interface file
//Interface.h
class A
{
virtual method1();
};
//b.h
#include "Interface.h"
class B : public A
{
//declaration
}
//b.cxx
#include b.h
B::method1()
{
//definition
}
I am exporting all these classes in a dll. And I am using methods and classes in the dll from an exe. This exe agains contains somes classes. These classes again inherit the same interface file and also uses method1(). So to use method1() I am including b.h in my file. If order of my include statements are Interface.h and b.h, then I am getting Compiler error for exe. Telling "base class not defined". But if I reorder the Include statement there is no compilation error. Can any one suggest me what could be basic reason for this problem.
There are actually two errors in your example code: First you do not declare the method without a return type, which is an error. The second is that you, at least in the snippet above, do not declare method1 in the class definition of B:
class B : public A
{
virtual void method1();
};
You absolutely need to declare virtual method "method1()" in both A and B's class definition.
If you interface is IA and is declared in IA.h , make sure that every class Foo that inherits from IA be it in the exe or dll includes IA.h before the class definition in Foo.h
What I suspect is happening that this is not the case and based on the header include order you might be getting the definition of IA in certain files and not in the others
So I have a vector of pointers to baseclass, which is used to hold all instances of derived classes.
Base class:
#ifndef BASE_H
#define BASE_H
Class Base
{
public:
virtual void DoSomething();
};
#endif
A derived class:
#ifndef DERIVED_H
#define DERIVED_H
#include "base.h"
Class Derived : public Base
{
public:
void DoSomething();
float y;
};
#endif
With these things being stored inside:
std::vector<Base*> theVec;
The question being, what is the best way to access the float variable "y" that exists only in Derived?
I could have a virtual function in Base that is specified in Derived to return a variable, where access looks like:
theVec[0]->GetVar("y");
but when Derived is likely to have multiple variables of different types that are not in base this seems like it will end up being quite messy. Are there any ways to make access to a unique variable in Derived more generic?
Any suggestions would be greatly appreciated!
You use dynamic_cast.
if (Derived* ptr = dynamic_cast<Derived*>(theVec[0])) {
// do something here
}
There is no elegant solution to this problem. If you have it, your design is probably flawed, and you should rethink it. Having special cases for sub-classes defeats the purpose of polymorphism (although I admit that sometimes it is the only solution).