Access static const variable from derived classes - c++

I want to set name property in each derived class. And also want to acess this value like Bar1::s_name . My below code doesn't work. So how should I archive my desire?
class Parent {
public:
static std::string getName() {
return s_name;
}
const static std::string s_name;
};
class Bar1 : public Parent {
public:
Bar1() : s_name("Bar1") {}
};
class Bar2 : public Parent {
public:
Bar2() : s_name("Bar2") {}
};
int main() {
Bar1 b;
b.getName();
return 0;
}

Presumably you are wanting to use this in some polymorphic context. If so, you can't use static methods, because they don't exhibit polymorphic behaviour. Additionally, static members will be the same for every instance, including derived objects.
You probably want something like this:
class Parent {
public:
virtual std::string getName() {
return "Parent";
}
};
class Bar1 : public Parent {
public:
virtual std::string getName() override {
return "Bar1";
}
};
class Bar2 : public Parent {
public:
virtual std::string getName() override {
return "Bar2";
}
};
If you also want to be able to access the name statically like Bar1::s_name, you need a static member for each class:
class Parent {
public:
virtual std::string getName() {
return s_name;
}
const static std::string s_name;
};
const std::string Parent::s_name = "Parent";
//likewise for the others

I thing you do not understand properly what static (in this context) means.
Variable defined as static in class means, that there is only one instance of it. So s_name in both Bar1 and Bar2 adresses to one variable.
Method defined as static in class means, that it is not bound to specific instance of that class, but rather to all (maybe none) instances of that class. So it is better to call static method using B::getName() instead of b.getName() (it is less confusing).
Also, because you defined s_name as const static you made that a constant, which compiler does even treat like a variable in runtime, but rather like a constant.

you should define all static variable. definition is missing in your code.
add below line to your program, it will work.
string Parent::s_name = "\0";

Related

How to initialize grandparent's (const) property in grandchild in C++?

I know this might look like a trivial question, but I haven't found really an elegant C++ solution to the following problem.
I want to represent a complex (tree-like) hierarchy of a "world" of objects. Let's say Animals. Every animal has some basic const properties.
Like for example a name. Then it also has some methods, but they are not significant for this problem.
class Animal {
public:
const char *GetName() const;
protected:
const char *name;
};
class Insect : public Animal {
...
};
class Butterfly : public Insect {
...
};
In this hierarchy I would like to initialize the name in every derived (grand)child. What is an elegant solution to this?
It is also important to say that in this "world" there be only instances of the tree leaves. That is, there will be no objects "Animal" or "Insect". But there will be objects "Butterfly", "Bee" or "Mosquito".
I know the "standard" way to do this is to put name into constructor:
Animal::Animal(const char *name) : name(name) {}
Insect::Insect(const char *name) : Animal(name) {}
Butterfly::Butterfly() : Insect("Butterfly") {}
But if there are more of these properties, the derived classes need also some initialization and the hierarchy has more levels it can become quite a mess:
Animal::Animal(const char *name) : name(name) {}
Vertebrate::Vertebrate(const char *name) : Animal(name) {}
Mammals::Mammals(const char *name) : Vertebrate(name) {}
Ungulate::Ungulate(const char *name) : Mammals(name) {}
Horse::Horse() : Ungulate("Horse") {}
Another option I can see is to drop the const and assign directly in the grandchild's constructor:
class Animal {
public:
const char *GetName() const;
protected:
std::string name;
};
Horse::Horse() {this->name = "Horse";}
But that is also not optimal, because the const is lost and it is more prone to errors (the initialization can be forgotten).
Is there some better way to do this?
Hm - hope that I get not locked out from SO for that answer, but you could use a virtual base class that implements the name-property. Thereby, you will not have to propagate initialization in a base class all way through the hierarchy but could directly address the "very base" constructor with the name-property. Furthermore, you will actually be enforced to call it in any "Grandchild"-class, so you can't forget it by accident:
class NamedItem {
public:
NamedItem(const char* _name) : name(_name) {}
const char *GetName() const;
protected:
const char *name;
};
class Animal : public virtual NamedItem {
public:
Animal(int mySpecificOne) : NamedItem("") {}
};
class Insect : public Animal {
public:
Insect(int mySpecificOne) : Animal(mySpecificOne), NamedItem("") {}
};
class Butterfly : public Insect {
};
The elegant solution is to pass arguments through initialisation. For example, if the "name" variable was the name of the Butterfly (such as "sally" or "david") then it would be obvious it has to be done through initialisation. If you are finding that is ugly, as it is here, it may indicate that your data decomposition/class heirarchy are at fault. In your example every Butterfly object would have an identical set of properties that really refer to their class rather than each instance, ie they are class variables not instance variables. This implies that the "Butterfly" class should have a static pointer to a common "Insect_Impl" object (which might have a pointer to a single "Animal_Impl" object etc) or a set of overridden virtual functions. (Below I only show one level of heirarchy but you should be able to work out more levels)
// Make virtual inherited functionality pure virtual
class Animal {
private:
std::string objName; // Per object instance data
public:
virtual ~Animal(std::string n): objName(n) {}
virtual std::string const& getName() = 0; // Per sub-class data access
virtual std::string const& getOrder() = 0; // Per sub-class data access
std::string const& getObjName() { return this->objName; }
};
// Put common data into a non-inherited class
class Animal_Impl{
private:
std::string name;
public:
Animal_Impl(std::string n): name(n);
std::string const& getName() const { return this->name; }
};
// Inherit for per-instance functionality, containment for per-class data.
class Butterfly: public Animal{
private:
static std::unique< Animal_Impl > insect; // sub-class data
public:
Butterfly(std::string n): Animal(n) {}
virtual ~Butterfly() {}
virtual std::string const& getName() override {
return this->insect->getName(); }
virtual std::string const& getOrder() override {
static std::string order( "Lepidoptera" );
return order; }
};
// Class specific data is now initialised once in an implementation file.
std::unique< Animal_Impl > Butterfly::insect( new Animal_Impl("Butterfly") );
Now using the Butterfly class only needs per-instance data.
Butterfly b( "sally" );
std::cout << b.getName() << " (Order " << b.getOrder()
<< ") is called " << b.getObjName() << "\n";
The issue with your alternative, or any alternative leaving name non-const and protected, is that there is no guarantee that this property is going to be setup properly by the subclasses.
What does the following class give you ?
class Animal {
public:
Animal(const char* something)
const char *GetName() const;
private:
const char *name;
};
The guarantee of the immutability of the Animal interface, which can be a big plus when doing multithreading. If an object is immutable, multiple threads can use it without being a critical resource.
I know the "standard" way to do this is to put name into constructor:
... But if there are more of these properties, the derived classes
need also some initialisation and the hierarchy has more levels it can
become quite a mess
It is not messy at all. Given that there is only one place where the members of object A are being initialised, and it is within the constructor of their subclasses.

Setting value from Derivered class, while accesing same value from base class

I am getting an issue for retrieving BaseClass correct enum value.
class BaseClass
{
public:
enum EntityId {
EN_NONE = 0,
EN_PLAYER = 1,
EN_PLATFORM,
EN_GROUND,
EN_OBSTACLE,
EN_OTHER
};
void setEntityId(EntityId id) { _Entityid = id; }
EntityId getEntityId() { return _Entityid; }
protected:
EntityId _Entityid;
};
and
class DeriveredClassA : public SomeClass, public BaseClass {....};
class DeriveredClassB : public SomeClass, public BaseClass {....};
The initialization goes like this
DeriveredClassA->setEntityId(BaseClass::EntityId::EN_PLAYER);
DeriveredClassB->setEntityId(BaseClass::EntityId::EN_OBSTACLE);
Which is placed into a different vector list correspoinding to that enum.
However, I am forced to use void* to do static_casts cats...
Like this:
BaseClass* EA = static_cast<BaseClass*>(bodyUserDataA); //bodyUserDataA and bodyUserDataB are both void*
BaseClass* EB = static_cast<BaseClass*>(bodyUserDataB);
And I am trying to retrieve using EA->getEntityId() and EB->getEntityId() so I could check which one is EN_PLAYER, which one is EN_GROUND and etc. So then I could up-class from base into derivered class and do other stuff with it.
Tried using with virtual, however somehow I am receiving 2 copies of _EntityID, which can be either the same or DIFFERENT between my Derivered and BaseClass of that one object.
Moreover, I can't cast right away into DeriveredClass, since the code checking would be huge, due to many different types of DeriveredClass'es (DeriveredClassA, DeriveredClassB, DeriveredClassC, DeriveredClassD) with their corresponding vector list.
My question is that How I need setup correctly both Base and Derivered class, so that I could access _EntityID from Baseclass which is the same of that DeriveredClass? My main problem might is that I used incorectly virtual functions, so I left on default to understand my issue.
P.S. This is mainly my c++ issue, other tags are added due to I am using game engine and physics engine for this case.
I believe that you want your code to look more like this:
class Entity
{
public:
enum Type {
EN_NONE = 0,
EN_PLAYER = 1,
EN_PLATFORM,
EN_GROUND,
EN_OBSTACLE,
EN_OTHER
};
Type getType() { return _type; }
protected:
Entity(Type type): _type(type) {}
private:
const Type _type;
};
Then your derived classes and usage of this base would be more like:
class PlayerEntity: public Entity, public SomeClass
{
public:
PlayerEntity(std::string name): Entity(EN_PLAYER), _name(name) {}
std::string getName() const { return _name; }
private:
std::string _name;
};
class PlatformEntity: public Entity, public SomeClass
{
public:
PlatformEntity(): Entity(EN_PLATFORM) {}
};
Initialization is then done like:
int main()
{
PlatformEntity platform;
std::vector<PlatformEntity> platforms(platform);
std::vector<PlayerEntity> players;
players.emplace_back("Bob");
players.emplace_back("Alice");
players.emplace_back("Ook");
}
Access from user-data could then look like this:
// bodyUserDataA and bodyUserDataB are both void*
Entity* const EA = static_cast<Entity*>(bodyUserDataA);
Entity* const EB = static_cast<Entity*>(bodyUserDataB);
switch (EA->getType())
{
case Entity::EN_PLAYER:
{
PlayerEntity* player = static_cast<PlayerEntity*>(EA);
std::cout << "Found player: " << player->getName();
break;
}
case Entity::EN_OTHER:
...
default:
break;
}

Implement possibility to access class member static as well as non-static on a derived class

I have the following classes.
// My baseclass
class Item {
public:
virtual const std::string GetItemName() = 0;
};
// My derived class
class Shovel : public Item {
private:
static const std::string _ITEM_NAME = "tool_shovel";
public:
const std::string GetItemName(){
return _ITEM_NAME;
}
}
With this i can access the names of my Item objects like this:
Item* myItem = new Shovel();
myItem.GetItemName(); // Returns "tool_shovel" ofcourse
I would now also like to access the name of an item without having an instance of it like this.
Shovel::GetItemName();
I know it is not possible to implement a virtual static function.
but is there any way to implement this in a 'nice' way or is this more a problem in my concept?
Thanks for the help!
I didn't know it is possible to call a static function directly from an instance, so i solved my problem now with 2 methods.
One public static function, so i can get the name of an item at any time. And another private non-static function to let the baseclass get the name of the current item.
Here is the code:
// My baseclass
class Item {
protected:
virtual const std::string _GetItemName() = 0;
};
// My derived class
class Shovel : public Item {
private:
static const std::string _ITEM_NAME = "tool_shovel";
protected:
const std::string _GetItemName(){
return _ITEM_NAME;
}
public:
static const std::string GetItemName(){
return _ITEM_NAME;
}
};
I hope this helps anyone. If you have questions feel free to ask.

How to make a member function in an inheritance hierarchy return always the same value?

I have an inheritance hierarchy and I want to make each class in this hierarchy have a set of attributes which are particular for that class and which do not change during the run of the program. For example:
class Base
{
public:
const std::string getName() const;
bool getAttribute1() const;
int getAttribute2() const;
};
Now I want these functions to return the same result all the time. Furthermore, when another class inherits Base this class should have its own set of attributes and any instance of this derived class should have the same attributes. Also the name should be unique for each class.
I want to know a way to make this as transparent and elegant as possible. Sofar I have considered 2 ideas that I can use:
Make some lock system.
That is provide setters for these attributes, but make them throw a runtime exception when they are called more than once.
Make the getters pure virtual.
In this case, the result of the functions would not be stored inside the object itself. This would make it vaguely clear that the result depends on the dynamic type.
Both ideas sound incredibly lousy, so I need your help.
I am new to C++, but I know there are a lot of idioms and patterns to solve general problems like this one. Do you know any?
I have an inheritance hierarchy and I want to make each class in this hierarchy have a set of attributes which are particular for that class and which do not change during the run of the program
Well, then just provide the corresponding values as arguments to a class constructor, and do not expose any setter method on the public interface. This will make sure the values remain constant throughout the life-time of the object.
To protect against possible errors that would alter the value of those data members from member functions of your class (which of course can access the private data), make those data members const. Notice, that this will force you to initialize those members in the constructor's initializer list.
class Base
{
public:
// Forwarding constructor (requires C++11)
Base() : Base("base", true, 42) { }
const std::string getName() const { return _s; }
bool getAttribute1() const { return _a1; }
int getAttribute2() const { return _a2; }
protected:
// Constructor that can be called by derived classes
Base(std::string s, bool a1, int a2)
: _s(s), _a1(a1), _a2(a2) { }
private:
const std::string _s;
const bool _a1;
const bool _a2;
};
Derived classes would then just construct the base subobject with the appropriate arguments:
class Derived : public Base
{
public:
// Provide the values for the constant data members to the base constructor
Derived() : Base("derived", false, 1729) { }
};
This way you would not incur in the overhead of a virtual function call, and you won't have to rewrite similar virtual functions for each of these members in derived classes.
Make them virtual and hard-code the result which the functions should return:
class Base
{
public:
virtual const std::string getName() const { return "BaseName"; }
virtual bool getAttribute1() const { return whatEverAttributeValueYouWant; }
virtual int getAttribute2() const { return attributeValueHere; }
};
class Derived : public Base {
public:
virtual const std::string getName() const { return "DerivedName"; }
virtual bool getAttribute1() const { return whatEverOtherAttributeValueYouWant; }
virtual int getAttribute2() const { return otherAttributeValueHere; }
};
If you want to describe classes rather than objects, use (kind-of) traits:
template<class T> struct AttributeValues;
template<> struct AttributeValues<Base> {
static const std::string name () { return "BaseName"; }
};
template<> struct AttributeValues<Derived> {
static const std::string name () { return "DerivedName"; }
};
//...
auto nameBase = AttributeValues<Base>::name ();
auto nameDerived = AttributeValues<Derived>::name ();

Overriding static variables when subclassing

I have a class, lets call it A, and within that class definition I have the following:
static QPainterPath *path;
Which is to say, I'm declaring a static (class-wide) pointer to a path object; all instances of this class will now have the same shared data member. I would like to be able to build upon this class, subclassing it into more specialised forms, layering behaviour, and with each class having its own unique path object (but not having to repeat the boring bits like calculating bounding boxes or calling the painting routines).
If I subclass it to create a class F (for example), I want F to use the inherited drawing routines from A, but to use the static (class-wide) path object declared in F. I have tried having the declaration above in the private section (and repeating it in the derived class F), and tried having it in the protected section, all with no joy.
I can sort of see why this is happening:
void A::paint() {
this->path...
is referring to A::path instead of F::path, even when the object is of class F.
Is there an elegant way to get round this, and allow each class to maintain a static path object, while still using drawing code defined in the base class, and having all classes (except perhaps the base class) be real and instantiatable?
Use a virtual method to get a reference to the static variable.
class Base {
private:
static A *a;
public:
A* GetA() {
return a;
}
};
class Derived: public Base {
private:
static B *b;
public:
A* GetA() {
return b;
}
};
Notice that B derives from A here. Then:
void Derived::paint() {
this->GetA() ...
}
You might be able to do a variant on a mix in or Curiously recurring template pattern
#include <stdio.h>
typedef const char QPainterPath;
class Base
{
public:
virtual void paint() { printf( "test: %s\n", getPath() ); }
virtual QPainterPath* getPath() = 0;
};
template <class TYPE>
class Holder : public Base
{
protected:
static QPainterPath* path;
virtual QPainterPath* getPath() { return path; }
};
class Data1 : public Holder<Data1>
{
};
class Data2 : public Holder<Data2>
{
};
template <> QPainterPath* Holder<Data1>::path = "Data1";
template <> QPainterPath* Holder<Data2>::path = "Data2";
int main( int argc, char* argv[] )
{
Base* data = new Data1;
data->paint();
delete data;
data = new Data2;
data->paint();
delete data;
}
I have just run this code in CodeBlocks and got the following:
test: Data1
test: Data2
Process returned 0 (0x0) execution time : 0.029 s
Press any key to continue.
I haven't tested this, but introducing a virtual function:
struct Base {
void paint() {
APath * p = getPath();
// do something with p
}
virtual APath * getPath() {
return myPath;
}
static APath * myPath;
};
struct Derived : public Base {
APath * getPath() {
return myPath;
}
static APath * myPath;
};
may be what you want. Note you still have to define the two statics somewhere:
APath * Base::myPath = 0;
APath * Derived::myPath = 0;
You can use virtual functions to achieve your result. This is probably your cleanest solution.
class A
{
protected:
virtual QPainterPath *path() = 0;
private:
static QPainterPath *static_path; /* Lazy initalization? */
};
QPainterPath *A::path()
{
return A::static_path;
}
class F : public A
{
protected:
virtual QPainterPath *path() = 0;
private:
static QPainterPath *F_static_path; /* Lazy initalization? */
};
QPainterPath *A::path()
{
return F::F_static_path;
}
I know this question has been answered, but there is an other way to set the value of a similar static variable for multiple classes through a helper class and some template specialization.
It doesn't exactly answer the question since it is not connected with subclassing in any way, but I've encountered the same issue and I found a different solution I wanted to share.
Example :
template <typename T>
struct Helper {
static QPainterPath* path;
static void routine();
}
// Define default values
template <typename T> QPainterPath* Helper<T>::path = some_default_value;
template <typename T> void Helper<T>::routine { do_somehing(); }
class Derived {};
// Define specialized values for Derived
QPainterPath* Helper<Dervied>::path = some_other_value;
void Helper<Dervied>::routine { do_somehing_else(); }
int main(int argc, char** argv) {
QPainterPath* path = Helper<Derived>::path;
Helper<Derived>::routine();
return 0;
}
Pros:
clean, compile time initialization
static access (no instantiation)
you can declare specialized static functions too
Cons:
no virtualization, you need the exact type to retrieve the information
You can't "override" static functions, let alone static member variables.
What you need is probably a virtual function. These can only be instance functions, so they will not be accessible without class instance.
You probably don't want static variables to the overriden. Maybe you can store a pointer in your class instead?
class A
{
public:
A() :
path(static_path)
{
}
protected:
A(QPainterPath *path)
: path(path)
{
}
private:
QPainterPath *path;
static QPainterPath *static_path; /* Lazy initalization? */
};
class F : public A
{
public:
F() :
A(F_static_path)
{
}
private:
static QPainterPath *F_static_path; /* Lazy initalization? */
};
If you don't care about the appearance just use A:: or F:: preceding the use of path to choose the correct one, or if you don't like :: name them differently.
Another option is to use a function to tidy this away, e.g. virtual QPainterPath* GetPath() { return A::path; } in A and QPainterPath* GetPath() { return F::path; } in F.
Really though this issue is just about how the code looks rather than what it does, and since it doesn't really alter readability I wouldn't fret about this...