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?
Related
In c++, Is there a standard way to create a function in a base class that can use the variables of derived classes?
class Foo{
private:
int x;
public:
Foo(){
x = 2;
}
void print(){
std::cout << x << std::endl;
}
};
class Derived : public Foo{
private:
int x;
public:
Derived(){
x = 4;
}
};
void main()
{
Derived a;
a.print();
}
This code prints the variable of the base class ( 2 ). Is there a way to make a function used by many derived classes to use the class's private variables without passing them as parameters?
Edit: My intentions are, to avoid writing the same code for each derived class.
For example, I want a get_var() in all, but this function should return the variable of that own class. I know I can make virtual and override, but I was looking for a way that I don't need to write again and again.
No, it is not possible for the base class to access anything in the derived class directly. The only way for a derived class to share anything with its base class is by overriding virtual member functions of the base class.
In your case, however, this is not necessary: the derived class can set variable x in the base class once you make it protected, and drop its own declaration as unnecessary:
class Foo{
protected: // Make x visible to derived classes
int x;
public:
Foo(){
x = 2;
}
void print(){
std::cout << x << std::endl;
}
};
class Derived : public Foo{
public:
Derived(){
x = 4;
}
};
I learnt the work of virtual functions: if the inherited classes inherit a function from the base class, and it is custom for each ones, I can call these functions with pointers that point to the base class, this way:
BaseClass* PointerName = &InheritedClassObject;
But what about variables? I found this question on the site that tells: I can't create virtual variables in C++. My experience proves it: for variables, Visual C++ says: 'virtual' is not allowed.
Then, what is the way to reach the value of a(n inherited) variable that belongs to an inherited class by using base class pointers?
Based off your comment, I think what you are trying to ask if how do child classes access their parent's variables. Consider this example:
class Parent
{
public:
Parent(): x(0) {}
virtual ~Parent() {}
protected:
int x;
};
class Child: public Parent
{
public:
Child(): Parent(), num(0) {}
private:
int num;
};
void Child::foo()
{
num = x; //Gets Parent's x,
}
NB: If you define an x in Child, that masks the x in Parent. So, if you want to get the x in Parent, you would need: Parent::x. To simply get x from a Child c, you use c.x if x is public or use a getter if x is protected or private:
int Child::getNum()
{
return num;
}
You don't. Virtual functions use them, do whatever needs to be done and return result if needed.
You can't use any function, data member of an inherited class if it's casted back to base class. However, you can alter those variables with virtual functions. Example:
#include <iostream>
class BaseClass {
public:
BaseClass() {}
virtual void do_smth() = 0;
private:
};
class InheritedClass: public BaseClass {
public:
InheritedClass(): a(1) {}
virtual void do_smth() { std::cout << ++a << std::endl; }
private:
int a;
};
int main() {
BaseClass* ptr = new InheritedClass();
ptr->do_smth();
return 0;
}
In this piece of code, virtual function did alteration of variable belongs to InheritedClass.
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;
}
I have these C++ classes:
class Base
{
protected:
static int method()
{
static int x = 0;
return x++;
}
};
class A : public Base
{
};
class B : public Base
{
};
Will the x static variable be shared among A and B, or will each one of them have it's own independent x variable (which is what I want)?
There will only be one instance of x in the entire program. A nice work-around is to use the CRTP:
template <class Derived>
class Base
{
protected:
static int method()
{
static int x = 0;
return x++;
}
};
class A : public Base<A> { };
class B : public Base<B> { };
This will create a different Base<T>, and therefore a distinct x, for each class that derives from it.
You may also need a "Baser" base to retain polymorphism, as Neil and Akanksh point out.
There will only be one, shared by all three classes. If you want separate instances, you will have to create separate functions in the derived classes.
I am pretty sure it will be shared between A and B.
If you want independent variables you can use the "Curiously Recurring Template Pattern" like:
template<typename Derived>
class Base
{
protected:
static int method()
{
static int x = 0;
return x++;
}
};
class A : public Base<A>
{
};
class B : public Base<B>
{
};
Of course if you want polymorphism, you would have to define a even "Baser" class which Base derives from, as Base<A> is different from Base<B> like:
class Baser
{
};
template<typename Derived>
class Base : public Baser
{
protected:
static int method()
{
static int x = 0;
return x++;
}
};
class A : public Base<A>
{};
class B : public Base<B>
{};
Now A and B can also be polymorphic.
The former. Local static variables are bound to the method containing them, and method exists in one incarnation for all subclasses (in fact, for the whole app, even though the rest of the program does not see the method).
The variable will be shared - it is per-function - in this case the function it belongs to is Base::method(). However if class Base was a template class you would get one instance of the variable for each instantiation (each unique set of actual template parameters) of class Base template - each instantiation is a new function.
If you are making X as static then it will be shared among all the child classes. No issues with the function being static.
class Base
{
public:
Base(){}
Base(int k):a(k)
{
}
int a;
};
class X:virtual public Base
{
public:
X():Base(10){}
int x;
};
class Y:virtual public Base
{
public:
Y():Base(10){}
int y;
};
class Z:public X,public Y
{
public:
Z():X(10){}
};
int main()
{
Z a;
cout << a.a;
return 1;
}
In the above case, for Z():X(10){} Base(int k):a(k) is not calling, but when i change to Z():Base(10){} the Base(int k):a(k) is called. Why ?
Thank you.
Because you used the virtual keyword - that's exactly what it does.
You have to explicitly initialize Base in the initializer list of Z in order to disambiguate between the initialization in X and the initalization in Y.
See this question. The gist is, that when using virtual inheritance you have to call the base class constructor explicitly.
The initializer list in the most derived constructor is used to initialize your base classes. Since class Z inherits from class X and Y which inherits from a common base class, the virtual keyword is used to create only a single subobject for the base class in order to disambiguate when accessing the data member a.