static variable for each derived class [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Overriding static variables when subclassing
I have a set of classes that are all derived from a base class. Any of these derived classes declare the same static variable. It is however specific to each of the derived classes.
Consider the following code.
class Base {
// TODO: somehow declare a "virtual" static variable here?
bool foo(int y) {
return x > y; // error: ‘x’ was not declared in this scope
}
};
class A : public Base {
static int x;
};
class B : public Base {
static int x;
};
class C : public Base {
static int x;
};
int A::x = 1;
int B::x = 3;
int C::x = 5;
int main() {}
In my base class I wanted to implement some logic, that requires the knowledge of the derived-class-specific x. Any of the derived classes has this variable. Therefore I would like to be able to refer to this variable at base class scope.
This wouldn't be a problem if it were a simple member variable. However, semantically, the variable is indeed not a property of the derived class' instance, but rather of the derived class itself. Therefore it should be a static variable.
UPDATE I need the class hierarchy to preserve its polymorphic nature. That is, all my derived class' instances need to be members of a common base class.
Then however, how can I get my hands on this variable from the base class method?

You can use the Curiously recurring template pattern.
// This is the real base class, preserving the polymorphic structure
class Base
{
};
// This is an intermediate base class to define the static variable
template<class Derived>
class BaseX : public Base
{
// The example function in the original question
bool foo(int y)
{
return x > y;
}
static int x;
};
class Derived1 : public BaseX<Derived1>
{
};
class Derived2 : public BaseX<Derived2>
{
};
Now classes Derived1 and Derived2 will each have a static int x available via the intermediate base class! Also, Derived1 and Derived2 will both share common functionality via the absolute base class Base.

With a virtual getter function
class Base {
public:
bool foo(int y) const{
return getX() > y;
}
virtual int getX() const = 0;
};
class A : public Base {
static const int x;
int getX() const {return x;}
};
class B : public Base {
static const int x;
int getX() const {return x;}
};
class C : public Base {
static const int x;
int getX() const {return x;}
};
int A::x = 1;
int B::x = 3;
int C::x = 5;
int main()
{
C c;
bool b = c.foo(3);
}

Related

Like, virtual function can we make a variable virtual in c++

when a base class pointer points to the object of it's derived class and if a function being overridden we use virtual function to solve the problem . So that we can access the own function of derived class using the pointer.
Like this , i was thinking that if there a way which can be applied on virtual keyword in variable , so that we can access the latest version of a variable in derived class using pointer.
#include <iostream>
using namespace std;
class base
{
public:
int x;//but what about this , if we add virtual keyword here.
//it will give error if trying to do so .
//but can you tell me what can i do if i want to make use of it as virtual function
//if not please tell me why
virtual void display(void) //to call the recent version of display function we make use of virtual here
{
cout << "base\n";
}
};
class derived : public base
{
public:
int x;
void display(void)
{
cout << "derived\n";
}
};
int main(void)
{
base *p;
base ob1;
derived ob2;
p=&ob2;
p->x=100;//here i want to set 100 to the x of derived class not that x which has been inherited
//But it sets to the x of base class which i dont wanted
p->display();//here we can access the latest version of display function in derived class
return 0;
}
Please, No body ask me why i want to do so.I don't have any intention to do in my real code. i asked for the curiosity.
No, you cannot use virtual for fields, only for methods.
However you can simulate that by creating a function that returns a reference to a field:
class Base
{
private:
int x;
public:
virtual int& X() { return x; }
};
class Derived : public Base
{
private:
int x;
public:
virtual int& X() override { return x; }
};
int main()
{
Derived d;
Base* b = &d;
b->X() = 100; // will set d's x
}
You can't override member variables with the virtual keyword. You could, however, have virtual getters and setters that refer to different member variables in the base and derived classes to achieve a similar effect:
class base {
public:
virtual int getX() {
return x;
}
virtual void setX(int x) {
this->x = x;
}
private:
int x;
}
class derived : public base {
public:
int getX() {
return x;
}
void setX(int x) {
this->x = x;
}
private:
int x;
}
The other answers are totally fine but you can also use the much simpler syntax:
class base {
public:
virtual operator int&() { return x; };
virtual operator int() { return x; };
protected:
int x;
};
if you have a single variable that you'd wish to virtualize in your class.
The second declaration is only to avoid using a reference when you just need the value, while when assigning the reference is automatically chosen for you.
You can override these operators at will from classes derived from base.
class derived : public base {
public:
operator int() override { return x * 5; };
}

Assign static variable to non-static variable

Consider the Base class where A class and BaseB class are derived. From BaseB is derived C class. All clases inherit non-static variable “y” but in the case of BaseB and C class “y” have the same value.
I resolved this situation with the following code:
class Base {
protected:
int y;
virtual void registerValue()
{
y = 5;
}
};
class A : public Base {
};
class BaseB : public Base {
protected:
static int x;
virtual void registerValue()
{
// Process x ...
y = x;
}
};
class C : public BaseB {
};
int BaseB::x = 3;
int main() {}
It works but is it right to assign static variable to non-static variable for this case?
It's fine to do from a language legality perspective, but it's a little odd.
Presumably you can't make Base::y static since that would interfere with the behaviour of class A?
You just need to be aware of the fact that instances of BaseB will all share the same x, but could have different values of y. Is that the intended behaviour?
Personally I'd consider making void registerValue() a pure virtual function in the base class, and expect all derived classes to implement that method including all necessary storage for its implementation. Perhaps that necessitates a base class function virtual int getRegistedValue() = 0 too?

Two child classes that only differ in a static const member

I have a class A and two children B and C as follows:
class A {
private:
int x;
template<class T>
void setX(T &y);
public:
A();
};
class B : public A {
private:
static const double y;
public:
B();
};
class C : public A {
private:
static const int y;
public:
C();
};
Both children only differ in the type of their static member y. The implementation of both C and B is the same except on the initialization of the static member:
B::B() : y (1.2) { setX(y) }
C::C() : y (2) { setX(y) }
But the problem with this approach is that in the implementation file I have to write twice the same code for B and C. Is there a proper way to write this such that I do not need to write twice the call to setX?
In the real problem the classes are a little more complicated, but the situation at hand is the same. In particular, initialization of y requires non-trivial constructors and so it has to be in the implementation file.
You can write a constructor for A as a function template.
class A {
//....
public:
template<typename T>
explicit A(T& y) {
setX(y);
}
};
And call that constructor from child classes:
class B : public A{
//...
public:
B() : A(1.2), y(1.2)
{}
};
Only problem is that base class constructor gets called first, so you need to repeat constant data value twice. You can easily macro it though.

How to Avoid Duplicate copies of Base Class Members in Derived Class in C++

In my project, there is one Base class and there are 3 different derived classes. I have some macro variables written as const int in the base class. All the derived member is going to access these members and are going to see the same value. Since, its a const, and it is not going to change, maintaining 3 different values will be waste of space. Hence I want a way to maintain just one copy of base class const members so that all the derived class will use the same.
Example
//Base.hpp
Class Base {
const int ZER0;
const int ONE;
};
//Derived1.hpp
class Derived1:public Base {
int some_method1();
};
//Derived1.cpp
int Derived1::some_method1() {
int value = ZERO;
}
//Derived2.hpp
class Derived2:public Base {
int some_method2();
};
//Derived2.cpp
int Derived2::some_method2() {
int value = ONE;
}
//main.cpp
Derived1 d1;
d1->some_method1();
Derived d2;
d2->some_method2();
//Here in both the methods the values are constant, but still the ZERO and ONE are going to have different space. Is there a way, where I maintain only one copy? I could think of static variable. Is it okay to use static inside class and where do I initialize the static variable. Please advice.
PS: This questions might be a duplicate, but I cant find something with similar words, if you feel this is, please feel free to redirect to the corresponding article/question;
If I'm understanding you correctly, would an enum do what you're looking for?
class Base
{
enum
{
ZERO,
ONE
};
};
I think you can possibly use virtual base inheritence to maintain one copy of base ..
//Base.hpp
class Base {
public:
Base() {}
virtual ~Base() {}
protected:
static const int ZER0;
static const int ONE;
};
//Base.cpp
const int Base::ZER0 = 0;
const int Base::ONE = 1;
//Derived1.hpp
class Derived1 : public virtual Base { //using virtual keyword here maintains one copy of base class, thus one copy of ONE and ZERO for all objects since they are static members of Base. You must read about diamond problem of virtual inheritence to understand this properly.
public:
Derived1() :Base() {}
int method1();
};
//Derived1.cpp
int Derived1::method1() {
int value = ZER0;
return value;
}
//Derived2.hpp
class Derived2 : public virtual Base {
public:
Derived2() :Base() {}
int method2();
};
//Derived2.cpp
int Derived2::method2() {
int value = ONE;
return value;
}
//main.cpp
int main() {
Derived1 d1;
d1.method1(); // . instead of -> , -> is used for member access through pointers
Derived2 d2;
d2.method2();
return 0;
}

Using Base class Static const variable for constructing Base Class, Can I do it?

I have a base and derived class. The base class constructors have some static const variables. Is it okay to use it in derived class constructor to construct base class variable??
an example code will be
//Base.hpp
class Base {
public:
Base(int value_, long sizee_);
private:
int value;
int sizee;
protected:
static const int ONE = 1;
static const int TWO = 2;
static const long INT_SIZE = (long)sizeof(int);
static const long LONG_SIZE = (long)sizeof(long);
};
//Base.cpp
Base::Base(int value_,int sizee_):value(value_),sizee(sizee_) {
}
//Derived.hpp
class Derived: class Base {
public:
Derived();
};
//Derived.cpp
Derived::Derived():Base(ONE+TWO,INT_SIZE+LONG_SIZE) {
}
Here ONE,TWO,INT_SIZE,LONG_SIZE are base class static variables, I will using it to construct the base class itself. Is this approach fine? Please advice.
Yes, it's fine. By the time you create a Dervide object, all static members are initialized. That is, unless you have static Derived objects.