Static variables in static method in base class and inheritance - c++

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.

Related

Selective static member inheritance with CRTP

so I have this class hierarchy using CRTP:
template <class T>
class A {
static Object x;
static OtherObject y;
}
class B : public A<B> {
}
class C : public A<C> {
}
The original idea is that B and C do not share instances of x and y, since A<B> and A<C> are considered separate classes. But suppose that it was determined, for resource savings, that 'x' should be a singleton instance shared by B and C while an instance of 'y' shoul still be created for each derived class. Is there a way to do this?
Thanks in advance.
You can make the class template derive from another class. Define x in the base class.
class ABase {
static Object x;
};
template <class T>
class A : public ABase {
static OtherObject y;
}
class B : public A<B> {
}
class C : public A<C> {
}

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?

Is this c++ inheritance structure possible?

I have not programmed in c++ in a long time and want some simple behavior that no amount of virtual keywords has yet to produce:
class Base {
public:
int both() { return a(); }
};
class Derived : public Base {
protected:
int a();
};
class Problem : public Derived {
};
Problem* p = new Problem();
p.both();
Which gives me a compile-time error. Is this sort of behavior possible with c++? Do I just need forward declaration? Virtual keywords on everything?
No. You will have to use a pure virtual a in base.
class Base {
virtual int a() = 0;
int both() {
return a();
}
};
You should declare the a() function as a pure virtual method in the Base class.
class Base {
int both() {
return a();
}
virtual int a()=0;
};
Then implement the a() method in the Derived class
class Derived : public Base {
int a(){/*some code here*/}
};
And finally, Problem class doesn't see the both() method, since its private in Base. Make it public.
class Base {
public:
int both() {
return a();
}
};
Your function both() is private by default. Try:
class Base {
public:
int both() {
// ...
(In the future, it would be helpful if you tell us what the actual error message was.)
You need a() to be declared in class Base, otherwise the compiler doesn't know what to do with it.
Also, both() is currently a private method (that's the default for classes), and should be made public in order to call it from main.
You have multiple problems in your code :
unless you declare them public or protected, elements of a class are private as a default.
you need a virtual keyword to define a virtual function that would be callable in a parent.
new returns a pointer to Problem.
Here's a complete working code based on your test :
class Base {
protected:
virtual int a()=0;
public:
int both() {
return a();
}
};
class Derived : public Base {
private :
int a()
{
printf("passing through a!");
return 0;
}
};
class Problem : public Derived {
};
int main(void)
{
Problem* p = new Problem();
p->both();
}
tested on CodePad.
As others point out, you need to declare a() as pure virtual method of Base and change access to public to make your snippet work.
Here is another approach possible in c++: instead of virtual functions, you can use static polymorphism via the Curiously recurring template pattern:
template <class D>
class Base : public D
{
public:
int both() { return D::a(); }
};
class Derived : public Base<Derived>
{
public:
int a();
};
I'm posting this approach since you're asking what is possible in c++. In practice, virtual methods are most often a better choice because of their flexibility.

C++ Design (behavior in base class, private member supplied in derived class)

I have 6 classes which all perform the same actions. I would like to move common behavior to a common [base] class.
There are actions to be performed on 6 separate objects. The six objects are located in derived classes. Intuitively, the private member objects would be accessed through the child (derived class) in the base class.
What is the C++ pattern I am looking for?
class Base
{
// Common behavior, operate on m_object
...
void Foo()
{
m_object.Bar();
}
};
class Derived1 : public Base
{
// No methods, use Base methods
private:
MyObject1 m_object;
}
class Derived2 : public Base
{
// No methods, use Base methods
private:
MyObject2 m_object;
}
The thing that is boxing me into this situation is MyObject1, MyObject2, etc offer Bar(), but don't share a common base class. I really can't fix the derivation because the objects come from an external library.
If they are introduced in the derived classes, then the base class cannot directly access them. How would the base class know that all derived classes have a specific member?
You could use virtual protected methods like so:
class my_base
{
protected:
virtual int get_whatever();
virtual double get_whatever2();
private:
void process()
{
int y = get_whatever();
double x = get_whatever2();
//yay, profit?
}
}
class my_derived_1 : my_base
{
protected:
virtual int get_whatever()
{
return _my_integer;
}
virtual double get_whatever2()
{
return _my_double;
}
}
Another possibility (if you want to call the base methods from the derived classes) is to simply supply the arguments to the base methods.
class my_base
{
protected:
void handle_whatever(int & arg);
};
class my_derived : my_base
{
void do()
{
my_base::handle_whatever(member);
}
int member;
};
C++ does and doesn't. It has a very powerful multiple inheritance support, so there is no super keyword. Why? Imagine that your base class is, say, inherited by another two classes, or even is a part of virtual inheritance hierarchy. In that case you can't really tell what super is supposed to mean. On the other hand, there are virtual methods, you can always have them in base class and implement in derived classes (that's what languages like Java do, except that they they don't have multiple class inheritance support). If you don't want to go with polymorphism, you can use something like this:
#include <cstdio>
template <typename T>
struct Base
{
void foo ()
{
std::printf ("Base::foo\n");
static_cast<T *> (this)->bar ();
}
};
struct Derived : Base<Derived>
{
void bar ()
{
std::printf ("Derived::bar\n");
}
};
int
main ()
{
Derived d;
d.foo ();
}
This is an extremely simple example - you can extend the above example with access control, friends, compile-time assertions etcetera, but you get the idea.
Have you considered not using inheritance?
class FooBar
{
MyObject m_object;
public:
FooBar(MyObject m): m_object(m) {}
//operate on different m_objects all you want
};
What about deriving your six separate objects from a common base class? Then you can declare virtual methods in that base class to create your interface, and then implement them in the derived object classes.
Maybe you just need a template instead of superclass and 6 derived classes?
It seems that you need to access not the parent's, but child's field. You should do it by introducing an abstract method:
class ParentClass
{
public:
void f();
protected:
virtual int getSomething() = 0;
};
ParentClass::f()
{
cout << getSomething() << endl;
}
class DerivedClass : public ParentClass
{
protected:
virtual int getSomething();
}
DerivedClass::getSomething() { return 42; }
If you need to access parent's method, just use ParentClass::method(...):
class ParentClass
{
public:
virtual void f();
};
class DerivedClass : public ParentClass
{
public:
virtual void f();
};
void DerivedClass::f()
{
ParentClass::f();
}

Create derived class instance from a base class instance without knowing the class members

Is this scenario even possible?
class Base
{
int someBaseMemer;
};
template<class T>
class Derived : public T
{
int someNonBaseMemer;
Derived(T* baseInstance);
};
Goal:
Base* pBase = new Base();
pBase->someBaseMemer = 123; // Some value set
Derived<Base>* pDerived = new Derived<Base>(pBase);
The value of pDerived->someBaseMemer should be equeal to pBase->someBaseMember and similar with other base members.
Why would you want to derive and pass the base pointer at the same time? Choose either, nothing stops you from having both. Use inheritance to do the job for you:
class Base
{
public:
Base(int x) : someBaseMemer(x) {}
protected: // at least, otherwise, derived can't access this member
int someBaseMemer;
};
template<class T>
class Derived : public T
{
int someNonBaseMemer;
public:
Derived(int x, int y) : someNonBaseMemer(y), T(x) {}
};
Derived<Base> d(42, 32); // usage
Though not the best of choices as design.
Why wouldn't you actually finish writing and compiling the code?
class Base
{
public: // add this
int someBaseMemer;
};
template<class T>
class Derived : public T
{
public: // add this
int someNonBaseMemer;
Derived(T* baseInstance)
: T(*baseInstance) // add this
{ return; } // add this
};
This compiles and runs as you specified.
EDIT: Or do you mean that someNonBaseMemer should equal someBaseMemer?
Declare someBaseMemr as public or change the declaration from class to struct:
class Base
{
public:
int someBaseMemer;
};
OR
struct Base
{
int someBaseMemr;
};
Remember that a class has private access to all members and methods by default. A struct provides public access by default.
Also, all derived classes should have public inheritance from Base.