Reputation:
I have a class with a member m_preferences
(a vector containing assocation between word and features).
In this class the m_preferences
is not static and thus any instance of the class has its specific m_preferences
.
class Base{
private:
Preferences m_preferences;
public:
...
}
I then created a derived class where m_preferences
become static because I wanted that each new instance of this class share the same data for preferences no matter what happens.
class Derived: public Base{
private:
static Preferences m_preferences;
public:
...
}
I got a linking error.
Is it possible to do what I want to do (transforming a non-static member into a static one through inheritance)?
If not what are the philosophy behind this impossibility? Was it planned?
Thank you,
Sincerely,
Ronan
Upvotes: 3
Views: 5167
Reputation: 1468
If I'm reading you right, you want to define a hierarchy of objects which will have either a static, or an individual, instance variable Preferences. Try this?
class Base
{
virtual ~Base();
virtual Preferences& MyPreferences() =0;
};
class DerivedA: public Base
{
public:
virtual ~DerivedA();
virtual Preferences& MyPreferences() { return m_preferences; }
private:
Preferences m_preferences;
};
class DerivedB: public Base
{
public:
virtual ~DerivedB();
virtual Preferences& MyPreferences() { return preferences; }
private:
static Preferences preferences;
};
Preferences DerivedB::preferences;
"Transforming", as Ali Shafai said it too, is not possible. The problem here is that "static" members are properties of the class itself rather than of individual objects, while virtual declarations and inheritance are about handling individual objects that may not be of the same class, uniformly, at a higher level of abstraction.
Upvotes: 4
Reputation: 63755
You are breaking the is-a rule of inheritance.
You are stating that Base
is a type that has its own Preferences
member, and you are stating that Derived
is a Base
.
It appears that your Base
and Derived
objects share some qualities, but not as a direct inheritance
I believe this well get the result you want
class TrueBase{
// Put data and functionality here that really is common for both types.
private:
virtual Preferences& get_preferences() = 0;
};
class Base : public TrueBase{
private:
virtual Preferences& get_preferences()
{
return m_preferences;
}
Preferences m_preferences;
};
class Derived: public TrueBase{
private:
virtual Preferences& get_preferences()
{
return m_preferences;
}
static Preferences m_preferences;
};
Upvotes: 1
Reputation: 67749
Short answer: you aren't using inheritance properly.
Long answer: You defined Base as being a type with individual Preferences. If Derived does not meet the "is-a" qualification (Derived is a type that also has per-instance preferences), than it should not inherit from Base.
Perhaps a better design (?):
class NotDerivedAnymore
{
private:
static Base m_base;
public:
...
}
Upvotes: 4
Reputation: 791699
You can't stop every instance of Base
- including every instance of Derived
- from having a per-instance Preferences member variable as this is guaranteed by the definition of the Base class.
What you have done is added a new static Preferences
member to the Derived
class, which means that as well as a per-instance Preferences
member associated with the base class you also have a global Preferences
instance shared between all the Derived
instances.
Because you have used the same name for these two members, in the context of a Parent
member function, using the indentifier m_preferences
will refer to the global shared instances unless you qualify it as in Base::m_preferences
.
Your link error is probably because you need to provide a definition of Derived::m_preferences
in one of your translation units.
e.g. in some.cpp, outside of any function bodies:
Preferences Derived::m_preferences;
Upvotes: 7
Reputation: 5161
Yes, it is by design you cannot change the signature of a member while inheriting it.
Upvotes: 1