In C++11, I can expose an enumerator which is protected in a base class, to users of a derived class, as follows:
class Base
{
protected:
enum Waldo { hidden, found };
};
class Derived : public Base
{
public:
using Base::Waldo;
}
void foo()
{
Derived::Waldo w = Derived::Waldo::found;
}
Unfortunately, in C++03, Derived::Waldo::found is illegal, and Derived::found is met with 'Base::Waldo Base::found' is protected within this context.
I could work around that by also writing a using for each enumerator:
class Derived : public Base
{
public:
using Base::Waldo;
using Base::hidden;
using Base::found;
}
void foo()
{
Derived::Waldo w = Derived::found; // works in C++03
}
but this can be really tedious to do if the enumerator has many enumerators. Is there a way to pull off this enum-exposing in C++03 without this tedium?
SCNR!
struct Wrap
{
enum Waldo { hidden, found };
};
class Base : protected Wrap
{
};
class Derived : public Base
{
public:
using Base::Wrap;
};
void foo()
{
Derived::Wrap::Waldo w = Derived::Wrap::found;
}
Edit: Or you put it inside:
class Base
{
protected:
struct Wrap
{
enum Waldo { hidden, found };
};
};
class Derived : public Base
{
public:
using Base::Wrap;
};
void foo()
{
Derived::Wrap::Waldo w = Derived::Wrap::found;
}
Well, I think there are lots of different ways to do this, depending on what you want to do with the enum. Here is one:
struct WaldoStates
{
enum States{hidden, found};
};
class Base
{
public:
typedef WaldoStates Waldo;
};
class Derived : public Base
{
};
void foo()
{
WaldoStates::States state = Derived::Waldo::found;
}
Now, this is good if simply want the states to be accessible with something like myClass::Waldo::hidden in any class of the inheritance tree. If you want to be able to set different states for some of the derived classes, you may want to do something like this instead:
struct WaldoStates
{
typedef int State;
};
struct DefaultWaldoStates : public WaldoStates
{
enum States{hidden, found};
};
struct OtherWaldoStates : public WaldoStates
{
enum States{stillHidden, alreadyFound};
};
class Base
{
public:
typedef DefaultWaldoStates Waldo;
};
class Derived : public Base
{
};
class OtherDerived : public Base
{
public:
typedef OtherWaldoStates Waldo;
};
void foo()
{
WaldoStates::State state0 = Derived::Waldo::found;
WaldoStates::State state1 = OtherDerived::Waldo::alreadyFound;
}
Related
Context: I'm doing some internal cleanup to move away from large & unwieldy data structures to more well-defined data structures.
Current
I have a class that does something like this:
class Base {
public:
virtual int DoStuff(BigType input);
};
Calling code:
std::vector<Base*> bases;
BigType input;
for (const auto& base : bases) {
base.DoStuff(input);
}
Child classes currently look like this:
class Child : public Base {
int DoStuff(BigType input) const override {
// do stuff
}
};
Attempted
I added an intermediate interface:
template <typename SmallType>
class FocusedBase : public Base {
public:
int DoStuff(BigType input) const override {
return DoStuff(SmallType(input));
}
virtual int DoStuff(SmallType input);
};
Child classes now look like this. Note that SmallType may differ across child classes:
class Child : public FocusedBase<SmallType> {
int DoStuff(SmallType input) {
// do stuff
}
};
Calling code remains the same.
Issue
I'd like to have new classes inherit from FocusedBase only, not Base. Any thoughts on how to do so?
If you want to disallow inheriting from Base directly you can make Base::Base() private and make FocusedBase a friend:
struct Base {
private:
Base() = default;
friend class FocusedBase;
};
struct FocusedBase : Base {};
struct Foo : Base {};
struct Bar : FocusedBase {};
int main() {
//Foo f; // error
Bar b; // ok
}
class Base
{
public:
static int GetType_S()
{
return 1;
}
virtual int GetType()
{
return GetType_S();
}
};
class Son1 : public Base
{
public:
static int GetType_S()
{
return 2;
}
virtual int GetType()
{
return GetType_S();
}
};
My Question is : When I need some other classes like "Son1,Son2..." ,every class should implement GetType and GetType_S function, This two functions is repeated.So How to design this classes gracefully to let son classes implement only one function?And It is best not to use macros.
You can have a class template that each SonN inherits from, which in turn inherits Base.
template <int Type>
class Middle : public Base
{
public:
static int GetType_S()
{
return Type;
}
virtual int GetType()
{
return GetType_S();
}
};
class Son1 : public Middle<2> {};
class Son2 : public Middle<3> {};
class Whatever : public Middle<42> {};
Or, if there is nothing else in those classes:
using Son1 = Middle<2>;
using Son2 = Middle<3>;
using Whatever = Middle<42>;
The program below fails, obviously, in the return expression:
#include <memory>
class Base {
public:
class Nested {
public:
int c;
};
};
class A : public Base {
public:
class Nested : public Base::Nested {
public:
int c = 1;
};
};
class B : public Base {
public:
class Nested : public Base::Nested {
public:
int c = 2;
};
};
int main() {
std::shared_ptr<Base> X = std::make_shared<A>();
return X::Nested.c;
};
How can I get Nested.c value of X?
In other words, I have one base class (Base) and two derived classes (A and B). Each derived class has a nested class (Nested). I want to called Nested.c from an instance X, which is dynamically selected as one of the derived classes.
Probably just a misconception about nested classes. A Nested class does not magically add members to it's parent class. You need to do that manually, for example:
class Base {
public:
class Nested {
public:
int c;
};
Nested nested; // member of nested class Base::Nested.
};
Keep in mind that Base::Nested, A::Nested and B::Nested are all different classes. Allthough they look similiar they are not related at all.
Maybe the following is what you want:
#include <memory>
class Base {
private:
class Nested {
public:
int c;
};
Nested nested; // member of nested class Base::Nested.
public:
virtual int getC() const { return this->nested.c; }
};
class A : public Base {
private:
class Nested {
public:
int c = 1;
};
Nested nested; // member of nested class A::Nested.
public:
int getC() const override { return this->nested.c; }
};
class B : public Base {
private:
class Nested {
public:
int c = 2;
};
Nested nested; // member of nested class B::Nested.
public:
int getC() const override { return this->nested.c; }
};
int main() {
std::shared_ptr<Base> X = std::make_shared<B>();
return (*X).getC();
};
Each class has it's own member of it's own nested class and returns c with a virtual getter.
I have three classes defined as:
class Base
{
public:
int myvar1;
int myvar2;
...
};
class Base2 : Base
{
public:
Base2(...) : Base(...)
{
}
};
template<typename T> class Derived
{
public:
Derived(...) : Base2(...)
{
}
};
I need to serialize the base class including also the derived classes with boost to send it via sockets. How can i do it?
EDIT 1
std::auto_ptr<Base2>(new Derived(...))
I'm looking for a clean way of doing this since a long time. In my problem, there exist 3 classes not sharing any parent in common but each having some methods with the same name (A.doSomething, B.doSomething, C.doSomething). Hence, having the same function signature, class D inheriting from A and using method doSomething() will "look the same" to E inheriting from B or C .
Here is a sketch of what I'd like to be able to do:
class Base {
public:
void myMethod(void) { doSomething(); }
};
class Independent {
public:
doSomething();
};
clase Derived : public Base : public Independent {
(...)
};
int main(void) {
Derived *derivedObject = new Derived();
derivedObject->myMethod();
}
In this problem, object of type "Independent" is provided by a library that I cannot change. I would like to define a base class that uses methods that are going to be inherited later on. I couldn't find a proper way of doing this using virtual inheritance without causing ambiguous compiling.
You've got a nasty situation there. One solution to this would be using the Curiously Recurring Template Pattern to perform the inheritance at compile-time, like this:
template <typename D>
class Base {
public:
void myMethod(void) { static_cast<D*>(this)->doSomething(); }
};
class Independent {
public:
void doSomething();
};
clase Derived : public Base : public Independent {
/*...*/
};
int main(void) {
Derived *derivedObject = new Derived();
derivedObject->myMethod();
}
Alternatively, you could choose to put a middleman class in between to forward to Independent (I assume you have many classes deriving from the same Base and Independent, and just don't want to have to do this for each class).
template <typename D>
class Base {
private:
virtual void doSomethingImpl();
public:
void myMethod(void) { doSomethingImpl(); }
};
class Independent {
public:
void doSomething();
};
class IndependentWrapper : public Base : public Independent {
private:
void doSomethingImpl() { Independent::doSomething(); }
};
clase Derived : public IndependentWrapper {
/*...*/
};
int main(void) {
Derived *derivedObject = new Derived();
derivedObject->myMethod();
}