I have an doubt, with C++ redefinition. I assign memory in Derived class, so I need that this memory is reserved in Base class. So, I need considered that the attibute in the Base class is the same that the attribute in the Derived class, and I don't know is that is possible in C++.
class Base {
protected:
float * a;
Base() {}
public:
virtual void reset() {
a = 0;
}
virtual void exec() {
printf("Memory a: %x\n",a);
}
};
class Derivada: virtual public Base {
protected:
float * a;
Derivada() {}
virtual void reset() {
a = new float[256];
}
};
int main() {
Derivada *hija= new Derivada();
hija->reset();
hija->exec();
delete hija;
}
I really need do overloading, because it is an example of my real problem. I have the same test (Derived an main, code), for two different class Base, one in each branch, of my two branchs, of CVS.
In one of this class Base, I have this attributes, an in the other class Base, I don't have this attributes, so I have to put it, in Derived class, for compiling.
I wouldn't like to have to make two different test codes, so I need override the attribute
You could do something like this (but requires C++11):
#include <type_traits>
// A way to check for 'attr' data member presence/absence using SFINAE
template<class T> constexpr auto missing_attr(T) -> decltype(T::attr, bool())
{
return false;
}
constexpr bool missing_attr(...) { return true; }
struct Base { /* There might be (or not) a float data member 'attr' */ };
template<bool> struct Inject;
template<> struct Inject<true> { float attr = 0.0; };
template<> struct Inject<false> {};
struct Derived : public Base, protected Inject<missing_attr(Base())>
{
void do_something_with_attr()
{
// Derived has only one 'float attr' (it can be from Base or from Inject).
a *= a;
}
};
There are other ways to detect if a data member exists, e.g. the member detector idiom (C++03 compatible).
Do not redeclare the member the the derived class. The word "protected" ensures visibility.
If you redeclare the member, you will have a new member. This is called shadowing. See, e.g.
http://www-personal.umich.edu/~saarela/programming/2009/07/c-variable-shadowing.html
http://en.wikipedia.org/wiki/Variable_shadowing
Related
UPDATE: the behaviour is not template specific, so
struct Derived : public Base {
OverrideFoo* m_data {new OverrideFoo()};
}
will do the same. so it seems m_data in Derived and m_data in Base both exist in memory layout. If we define a function in Derived,
e.g., Derived::print() { m_data->print()}, this will use m_data in Derived, however, if base function is called on derived object, it still use m_data from Base.
I was surprised with the behaviour of the following code, it prints "from foo", rather than the "from override foo". why is it like this? shouldn't the "m_data" be the type of "OverrideFoo"?
#include <iostream>
using namespace std;
struct Foo {
void print() {
printf("from foo\n");
}
};
struct OverrideFoo {
void print() {
printf("from override foo\n");
}
};
struct Base {
void useData() {
m_data->print();
}
Foo* m_data {new Foo()};
};
template <class t>
struct Derived : public Base {
t* m_data {new t()};
};
int main()
{
Derived<OverrideFoo> d;
d.useData();
return 0;
}
When you call d.useData(), you are calling Base::useData(), which accesses Base::m_data.
I suppose you're expecting Base::useData() to use Derived::m_data, just because the variable has a similar name. However that's not how this works. Both classes get their own independent m_data, and in your case, with different types.
It's true that Derived::m_data hides Base::m_data, which may suggest to you that they are related or that one "overrides" the other. Don't confuse that with hiding. The hiding is a natural consequence of the similar naming. If Derived needs to access Base::m_data, it must qualify it in order to disambiguate from its own m_data.
Note: Member variables / fields cannot be overridden. If you need an override-style behavior, you'll need to do it via a member function (something like virtual IPrintable* GetPrintable(). And the base class must grant the possibility of overriding with the virtual keyword.
Another way to think about this: Base, despite what its name suggests, is a complete type. You can do Base x; to instantiate and use this class, without being derived. The compiler generates code for Base which is complete and functional, including the code to access Base::m_data. If m_data were somehow overrideable, how could this code be generated? What would Base understand sizeof(*m_data) to be, if its datatype could be overridden in some base class? How would the compiler know what m_data even refers to, if you're suggesting it can be changed by any class which derives it?
Another point: If members were able to be overridden by default (without the virtual keyword), it would cause mass chaos for base classes. Imagine writing a generic base class and risking that derived classes could unknowingly change the state of the base? Or imagine writing a derived class and being concerned about your variable naming because "well maybe a base class used the same name?"
So let's summarize the key points:
Fields cannot be overridden, period. It would break sizeof() among lots of other things (whole other topic)
Base classes must explicitly grant derived classes to override member functions via the virtual keyword.
There are probably better ways to do what you're attempting though. The most natural for me would be to specify the Foo type as a template parameter to Base.
Like this:
struct Foo1 {
void print() {
printf("from foo\n");
}
};
struct Foo2 {
void print() {
printf("from override foo\n");
}
};
template<typename TData>
struct Base {
void useData() {
m_data.print();
}
TData m_data;
};
template <typename TData>
struct Derived : public Base<TData> {
};
int main()
{
Derived<Foo1> d1;
d1.useData();
Derived<Foo2> d2;
d2.useData();
return 0;
}
It's hard to know the best approach for you, because this is an unrealistic contrived example.
Try this code out and you will find that the two m_data has different memory address, which means they are different variable.
#include <iostream>
using namespace std;
struct Foo {
void print() {
printf("from foo\n");
}
};
struct OverrideFoo {
void print() {
printf("from override foo\n");
}
};
struct Base {
void useData() {
m_data->print();
std::cout << m_data << std::endl;
}
Foo* m_data {new Foo()};
};
template <class t>
struct Derived : public Base {
t* m_data {new t()};
};
int main()
{
Derived<OverrideFoo> d;
d.useData();
d.m_data->print();
std::cout << d.m_data << std::endl;
return 0;
}
I'm writing a module system for my program, where individual modules are initialised and shutdown by a system.
how this works is I call an Init() function that will initialise a static pointer of the class.
this works and is fine, however: I would like to abstract this into a class so the api is easier to maintain, but I don't know how to change the pointer type of the derived class automatically
for example, if I have the base class IModule:
class IModule {
public:
protected:
result Init();
result Shutdown();
private:
static IModule* s_instance;
};
is there a way I can write this class so that the derived class can be written as
class Derived : public IModule {
protected:
result Init();
result Shutdown();
}
and have Derived::s_instance evaluate to a Derived*
No, you can't have a variable whose type depends on the type of this. However, you can have a variable whose type depends on a template parameter.
template <typename T>
class IModule {
private:
static T* s_instance;
};
class Derived : public IModule<Derived> {
// The s_instance in this class is of type Derived*.
}
This is called the curiously recurring template pattern and it's used to do all sorts of tricks in C++. It may not work for your use case (for instance, you can no longer have a list of IModule which all have different derived types), but depending on what exactly you're doing this may be the way to go.
You can do this as long as the return types are covariant, i.e., Derived::Init() returns something derived from Derived::IModule()'s return type. Which is I think the case here. A simplified version:
#include <iostream>
struct IModule {
virtual IModule* Init() = 0;
private:
static IModule* s_instance;
};
class Derived : public IModule {
Derived* Init() override { std::cout << "1" << std::endl; return this; }
};
int main() {
IModule* ptr = new Derived();
ptr->Init(); // compile-time type: IModule, runtime: Derived
}
Given a base class Base that has two derived classes, DerA and DerB, can the derived classes have a member variable that is used in a Base member function, but is a different type for each class?
class Base {
* a // Declare a as *something*, so it can be used by "doWork"
template <typedef T>
void doWork(T b) { // Add another value to "a" which is of its same type
a += b; // For example; an operation that works on "a", no matter what numeric type it is
}
}
class DerA : public Base {
// Make "a" an int
}
class DerB : public Base {
// Make "a" a float
}
In practice, a will be a base struct, while DerA and DerB will have derived versions of the base struct (derivative classes will each have a derived form of the struct specific to their purpose, but each must do a simple operation on a, so it seems pointless to copy/paste that simple function for each derivative when I can just use a template function). I would just type a as the base struct type, but then I lose access to the various specialized member functions and variables that each derived struct has (if I understand inheritance correctly).
I apologize if this question is a repeat, but I don't know what this quality would be called, so Googling proved fruitless.
What you might want is the CRTP.
template<class D>
struct Base {
D* self() { return static_cast<D*>(this); }
D const* self() const { return static_cast<D*>(this); }
template<class T>
void doWork(T b) {
self()->a += b;
}
};
struct DerA : public Base<DerA> {
int a;
};
struct DerB : public Base<DerB> {
double a;
};
Here we pass the derived type to our base class. Within the base class, you can use self()-> to access fields in the derived type. This allows basically full access to the derived type, while letting us share code in the base class.
Note that you cannot pass DerA and DerB around as a Base this way. If you want that, you need a virtual method doWork, and virtual template methods don't exist.
CRTP stands for the curiously repeating template pattern, which I imagine is named because it is strange, it involves repeating a type, and it keeps on showing up in strange corners as being useful.
Type erasure probably won't work either, as you want to dispatch the type erasure from two different spots in the code base (the double dispatch problem: you need a centralized list of types supported to do the type Cartesian product on).
To expand on that, in order to support a+=b where both a and b are arbitrary types, you would have to expand over all types twice over, including types that are never mutually visible at the same spot in a compilation unit. That isn't possible.
If you need a common base, and there are only some types you pass to doWork, here is how you do it:
struct Base {
virtual void doWork( double ) = 0;
virtual void doWork( int ) = 0;
virtual void doWork( long long ) = 0;
};
template<class D>
struct Base_helper:Base {
D* self() { return static_cast<D*>(this); }
D const* self() const { return static_cast<D*>(this); }
template<class T>
void doWork_impl(T b) {
self()->a += b;
}
void doWork( double x ) override { doWork_impl(x); };
void doWork( int x ) override { doWork_impl(x); };
void doWork( long long x ) override { doWork_impl(x); };
};
struct DerA : public Base_helper<DerA> {
int a;
};
struct DerB : public Base_helper<DerB> {
double a;
};
note that every version of doWork must be valid to call on each of the Ders, as the Base_helper instantiates all of them.
If the kind of type passed to doWork is unbounded, yet the types of Der is bounded, you can do something like the above only backwards. It gets awkward, however. Your best bet in that kind of situation is to use a boost::variant type solution.
I guess you want to achieve something like this:
template<typedef T>
class Base {
T a;
void doWork(T b) { // Add another value to "a" which is of its same type
a += b; // For example; an operation that works on "a", no matter what numeric type it is
}
}
class DerA : public Base<int> {
}
class DerB : public Base<float> {
}
Or you can dump classes DerA and DerB entirely and use typedefs instead:
typedef Base<int> DerA;
typedef Base<float> DerB;
This can be easily solved with a CRTP-like pattern:
template<class D> // Base class is templated
class Base {
public:
D a;
void doWork(D b) {
a += b;
}
};
class DerA : public Base<int> {};
class DerB : public Base<float> {};
Live Example
Edit: in case you need only one common base (Base<int> is a completely different type from Base<float>) you might use an interface class and have Base inherit from it.
In the header file .hpp:
class Base{
public:
static /*Some Return Type*/ func(/*Some Datatype*/);
}
class Derived1 public Base{
public:
Derived1();
~Derived1();
}
class Derived1 public Base{
public:
Derived2();
~Derived2();
}
In the cpp file .cpp:
/*Some Return Type*/ Derived1::func(/*Some Datatype*/){
}
/*Some Return Type*/ Derived2::func(/*Some Datatype*/){
}
This obviously fails because there is no way to override a static method in a subclass. But how to obtain the above functionality?
It is mandatory for me to call something like this:
/*Some Return Type*/ result = Derived1::func(/*Some Datatype*/)
/*Some Return Type*/ result = Derived2::func(/*Some Datatype*/)
I know, that abstract method can be defined in the base class like below and then define them in Derived class:
In the header file .hpp:
class Base{
public:
virtual /*Some Return Type*/ func(/*Some Datatype*/) const = 0;
}
But the problem is that virtual methods require object instantiation, which is not I want. I want to call the method without creating an object. If virtual static methods were allowed, they would have served the purpose.
The only alternative that I can think of is to declare the function func() in all the Derived classes in the header file and remove it from the Base class. Is there any alternative method to do it? So that the declaration is only once in the Base class and all the Derived classes only have to define them, not redeclare?
Calling a virtual function without an object is a contrasense,
since the resolution depends on the type of the object.
are cases where you might need to call the same function
dependant on the type of an object, or specifying the class
explicitly, without an object. This is easily handled by using
two functions, one static, and one virtual. (Typically, the
virtual one will just forward to the static.)
EDIT:
A simple example (from actual code):
#define DECLARE_CLASS_NAME(className) \
static char className() { return STRINGIZE(className); } \
virtual char* getClassName() { return className(); }
class Base
{
public:
DECLARE_CLASS_NAME(Base);
// ...
};
class Derived : public Base
{
public:
DECLARE_CLASS_NAME(Derived);
// ...
};
and so on, in all of the derived classes. This was used to
obtain the type names for serialization, for example:
std::string typeName = pObj->getClassName();
and also as a primitive RTTI (this was about 20 years ago):
if ( pObj->getClassName() == Derived::className() ) ...
(We had established the rule that the only way you could obtain
the name of a class was by using one of these functions. That
effectively internalized the names of the classes, and allowed
simple pointer comparisons to work. On the systems we were
working on then, this was important.)
You can do that a bit hacky =)
//header file
template<class T>
struct base_t
{
static void do_smth();
};
struct derived1_t : base_t<derived1_t>
{
};
struct derived2_t : base_t<derived2_t>
{
};
//cpp file
void base_t<derived1_t>::do_smth() // `note base_t<derived1_t>::` instead of `derived1_t::`
{
std::cout << "aaa" << std::endl;
}
PS: very strange that you do not want to declare this function in derived classes, because when you use virtual functions you should declare them in derived class
One possibility is to only define them in the derived classes:
struct Base
{
// nothing
};
struct Derived1 : public Base
{
static void func() { /*...*/ }
};
struct Derived2 : public Base
{
static void func() { /*...*/ }
};
This allows you to call:
Derived1::foo();
Derived2::foo();
Calling it for the base type and expecting the compiler to figure out which subtype you mean cannot work:
// How will the compiler know to choose
// between Derived1:: func or Derived2:: func ?
Base::func();
You might want to look at CRTP or type-traits for alternative approaches.
Say B and C are derived from A. I want to be able to test whether any two instances of classes derived from A are instances of the same class, that is, whether A* foo and A* bar both point to B instances, without using RTTI. My current solution is something like this:
class A {
protected:
typedef uintptr_t Code;
virtual Code code() const = 0;
}; // class A
class B : public A {
protected:
virtual Code code() const { return Code(&identity); }
private:
static int identity;
}; // class B
class C : public A {
protected:
virtual Code code() const { return Code(&identity); }
private:
static int identity;
}; // class C
Using this method, operator== can simply test first.code() == second.code(). I'd like to remove the literal identity from the derived classes and have the code found automatically by A, so that not all of the derived classes have to repeat this idiom. Again, I would strongly prefer not to use RTTI. Is there any way to do this?
Note: I have seen recent questions [1] and [2], and this is not a duplicate. Those posters want to test the contents of their derived classes; I merely want to test the identities.
You should just use RTTI instead of reinventing the wheel.
If you insist on not using RTTI, you could use CRTP and a function-local static variable to avoid having to write the function to every derived class. Adapt from this example code I wrote for Wikipedia: http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern#Polymorphic_copy_construction
Another alternative is reading the vtable pointer (via this and pointer arithmetics), but that would depend on both the compiler and the platform, so it is not portable.
Your idea is on the right track; maybe you can eliminate some boilerplate with a template:
class TypeTagged {
public:
virtual Code code() const = 0;
}
template <class T>
class TypeTaggedImpl: public virtual TypeTagged {
public:
virtual Code code() const { return Code(&id); }
private:
static int id;
}
Then your client classes just need to be declared like this:
class A: public TypeTaggedImpl<A> { ... }
class B: public A, public TypeTaggedImpl<B> { ... }
The different instantiations of TypeTagged mean that the types have different id fields and hence different IDs; the virtual base type means that the code for the most derived type gets returned.
You can have the Base class to take id as a constructor parameter and implement the identity() function in base class itself. Then there is no need to repeat the code in derived classes. In the derived class constructor, you can do something like derived::derived(): base(0) Sample Code:
class A
{
public:
A(int n) : m_id(n)
{
}
virtual ~A(){}
virtual int id() const
{
return m_id;
}
private:
int m_id;
};
class B : public A
{
public:
B() : A(0)
{
}
};
you can use the both macro __FILE__ __LINE__ as your code
this will avoid the collision problem
you can map this values to an int