I have something like this:
class Base
{
public:
static int Lolz()
{
return 0;
}
};
class Child : public Base
{
public:
int nothing;
};
template <typename T>
int Produce()
{
return T::Lolz();
}
and
Produce<Base>();
Produce<Child>();
both return 0, which is of course correct, but unwanted. Is there anyway to enforce the explicit declaration of the Lolz() method in the second class, or maybe throwing an compile-time error when using Produce<Child>()?
Or is it bad OO design and I should do something completely different?
EDIT:
What I am basically trying to do, is to make something like this work:
Manager manager;
manager.RegisterProducer(&Woot::Produce, "Woot");
manager.RegisterProducer(&Goop::Produce, "Goop");
Object obj = manager.Produce("Woot");
or, more generally, an external abstract factory that doesn't know the types of objects it is producing, so that new types can be added without writing more code.
There are two ways to avoid it. Actually, it depends on what you want to say.
(1) Making Produce() as an interface of Base class.
template <typename T>
int Produce()
{
return T::Lolz();
}
class Base
{
friend int Produce<Base>();
protected:
static int Lolz()
{
return 0;
}
};
class Child : public Base
{
public:
int nothing;
};
int main(void)
{
Produce<Base>(); // Ok.
Produce<Child>(); // error :'Base::Lolz' : cannot access protected member declared in class 'Base'
}
(2) Using template specialization.
template <typename T>
int Produce()
{
return T::Lolz();
}
class Base
{
public:
static int Lolz()
{
return 0;
}
};
class Child : public Base
{
public:
int nothing;
};
template<>
int Produce<Child>()
{
throw std::bad_exception("oops!");
return 0;
}
int main(void)
{
Produce<Base>(); // Ok.
Produce<Child>(); // it will throw an exception!
}
There is no way to override a static method in a subclass, you can only hide it. Nor is there anything analogous to an abstract method that would force a subclass to provide a definition. If you really need different behaviour in different subclasses, then you should make Lolz() an instance method and override it as normal.
I suspect that you are treading close to a design problem here. One of the principals of object-oriented design is the substitution principal. It basically says that if B is a subclass of A, then it must be valid to use a B wherever you could use an A.
C++ doesn't support virtual static functions. Think about what the vtable would have to look like to support that and you'll realize its a no-go.
or maybe throwing a compile-time error when using Produce<Child>()
The modern-day solution for this is to use delete:
class Child : public Base
{
public:
int nothing;
static int Lolz() = delete;
};
It helps avoid a lot of boilerplate and express your intentions clearly.
As far as I understand your question, you want to disable static method from the parent class. You can do something like this in the derived class:
class Child : public Base
{
public:
int nothing;
private:
using Base::Lolz;
};
Now Child::Lolz becomes private.
But, of course, it's much better to fix the design :)
Related
I'd like to be able to group similar functions in a class into a group so I don't need to append each name with what it's about.
I've seen this question which says that you can't have namespaces within classes. I've also seen this question which proposes using strongly typed enums. The problem here though, is that I'm not sure whether or not these enums can actually accomodate functions?
The problem contextualised:
class Semaphore
{
public:
void Set(bool State){Semaphore = State;}
bool Get(){return Semaphore;}
void Wait()
{
while (Semaphore)
{
//Wait until the node becomes available.
}
return;
}
private:
bool Semaphore = 0; //Don't operate on the same target simultaneously.
};
class Node : Semaphore
{
public:
unsigned long IP = 0; //IP should be stored in network order.
bool IsNeighbour = 0; //Single hop.
std::vector<int> OpenPorts;
//Rest of code...
};
Currently, NodeClass.Get() is how I can get the semaphore. However this introduces confusion as to what Get() actually gets. I'd like to have something akin to NodeClass.Semaphore::Get(). Otherwise I'd have to have the functions as SemaphoreSet(), SemaphoreGet(), and SemaphoreWait(), which isn't too well organised or nice looking.
I had thought of just having the Semaphore class on it's own, and instantiating it within the other classes, but if I could stick with the inheritance approach, that would be nicer.
So essentially, is it possible to access inherited methods like InheritedClass.Group::Function()?
If you really want to do this, you could force the user to call with the base class name by deleteing the member function in the subclass:
class Base {
public:
void Set(bool) { }
};
class Derived : public Base {
public:
void Set(bool) = delete;
};
int main() {
Derived d;
// d.Set(true); // compiler error
d.Base::Set(true);
}
However, if the semantics of calling Set on the subclass are significantly different than what you'd expect them to be when calling Set on the base class, you should probably use a data member and name a member function accordingly as you've described:
class Base {
public:
void Set(bool) { }
};
class Derived {
public:
void SetBase(bool b) {
b_.Set(b);
}
private:
Base b_;
};
int main() {
Derived d;
d.SetBase(true);
}
My question is more or less identical to the one at Need a design pattern to remove enums and switch statement in object creation However I don't see that the abstract factory pattern suits well here.
I'm currently planning the refactoring/reimplementation of some existing DAL/ORM mixture library. Somewhere in the existing code there is code that looks like this:
class Base
{
static Base * create(struct Databasevalues dbValues)
{
switch(dbValues.ObjectType)
{
case typeA:
return new DerivedA(dbValues);
break;
case typeB:
return new DerivedB(dbValues);
break;
}
}
}
class DerivedA : public Base
{
// ...
}
class DerivedB : public Base
{
// ...
}
So the library responsible for database communication populates a struct with all information about the database entity and then the above create() method is called to actually create the corresponding object in the ORM.
But I don't like the idea of a base class knowing of all its derived classes and I don't like the switch statement either. I also would like to avoid creating another class just for the purpose of creating those Objects. What do you think about the current approach? How would you implement this functionality?
This has been discussed here milliions of times. If you don't want to create a separate factory class, you can do this.
class Base
{
public:
template <class T>
static void Register (TObjectType type)
{
_creators[type] = &creator<T>;
}
static Base* Create (TObjectType type)
{
std::map <TObjectType, Creator>::iterator C = _creators.find (type);
if (C != _creators.end())
return C->second ();
return 0;
}
private:
template <class T>
static Base* creator ()
{
return new T;
}
private:
typedef Base* (::*Creator) ();
static std::map <TObjectType, Creator> _creators;
};
int main ()
{
Base::Register <Derived1> (typeA);
Base::Register <Derived2> (typeB);
Base* a = Base::Create (typeA);
Base* b = Base::Create (typeB);
}
Let's say you replace the switch with a mapping, like map<ObjectType, function<Base* (DatabaseValues&)>>.
Now, the factory (which may or may not live in the base class), doesn't need to know about all the subclasses.
However, the map has to be populated somehow. This means either something populates it (so your knowing about all subclasses problem has just been pushed from one place to another), or you need subclasses to use static initialization to register their factory functions in the map.
No matter what you do, you'll need either switch-case or some other construct that will just hide similar logic.
What you can and should do, however, is remove the create method from your Base - you're totally correct it shouldn't be aware of it's derived ones. This logic belongs to another entity, such as factory or controller.
Just don't use enums. They are not OO construction, that was why JAVA did not have them at the beginning (unfortunately the pressure was too big to add them).
Consider instead of such enum:
enum Types {
typeA,
typeB
};
this construction, which do not need switch (another non OO construction in my opinion) and maps:
Types.h
class Base;
class BaseFactory {
public:
virtual Base* create() = 0;
};
class Types {
public:
// possible values
static Types typeA;
static Types typeB;
// just for comparison - if you do not need - do not write...
friend bool operator == (const Types & l, const Types & r)
{ return l.unique_id == r.unique_id; }
// and make any other properties in this enum equivalent - don't add them somewhere else
Base* create() { return baseFactory->create(); }
private:
Types(BaseFactory* baseFactory, unsigned unique_id);
BaseFactory* baseFactory;
unsigned unique_id; // don't ever write public getter for this member variable!!!
};
Types.cpp
#include "Types.h"
#include "Base.h"
#include "TypeA.h"
#include "TypeB.h"
namespace {
TypeAFactory typeAFactory;
TypeBFactory typeAFactory;
unsigned unique_id = 0;
}
Types Types::typeA(&typeAFactory, unique_id++);
Types Types::typeA(&typeBFactory, unique_id++);
So your example (if you really would need this function then):
class Base
{
static Base * create(struct Databasevalues dbValues)
{
return dbValues.ObjectType.create();
}
};
Missing parts should be easy to implement.
I'm finding it difficult to describe this problem very concisely, so I've attached the code for a demonstration program.
The general idea is that we want a set of Derived classes that are forced to implement some abstract Foo() function from a Base class. Each of the derived Foo() calls must accept a different parameter as input, but all of the parameters should also be derived from a BaseInput class.
We see two possible solutions so far, neither we're very happy with:
Remove the Foo() function from the base class and reimplement it with the correct input types in each Derived class. This, however, removes the enforcement that it be implemented in the same manner in each derived class.
Do some kind of dynamic cast inside the receiving function to verify that the type received is correct. However, this does not prevent the programmer from making an error and passing the incorrect input data type. We would like the type to be passed to the Foo() function to be compile-time correct.
Is there some sort of pattern that could enforce this kind of behaviour? Is this whole idea breaking some sort of fundamental idea underlying OOP? We'd really like to hear your input on possible solutions outside of what we've come up with.
Thanks so much!
#include <iostream>
// these inputs will be sent to our Foo function below
class BaseInput {};
class Derived1Input : public BaseInput { public: int d1Custom; };
class Derived2Input : public BaseInput { public: float d2Custom; };
class Base
{
public:
virtual void Foo(BaseInput& i) = 0;
};
class Derived1 : public Base
{
public:
// we don't know what type the input is -- do we have to try to cast to what we want
// and see if it works?
virtual void Foo(BaseInput& i) { std::cout << "I don't want to cast this..." << std::endl; }
// prefer something like this, but then it's not overriding the Base implementation
//virtual void Foo(Derived1Input& i) { std::cout << "Derived1 did something with Derived1Input..." << std::endl; }
};
class Derived2 : public Base
{
public:
// we don't know what type the input is -- do we have to try to cast to what we want
// and see if it works?
virtual void Foo(BaseInput& i) { std::cout << "I don't want to cast this..." << std::endl; }
// prefer something like this, but then it's not overriding the Base implementation
//virtual void Foo(Derived2Input& i) { std::cout << "Derived2 did something with Derived2Input..." << std::endl; }
};
int main()
{
Derived1 d1; Derived1Input d1i;
Derived2 d2; Derived2Input d2i;
// set up some dummy data
d1i.d1Custom = 1;
d2i.d2Custom = 1.f;
d1.Foo(d2i); // this compiles, but is a mistake! how can we avoid this?
// Derived1::Foo() should only accept Derived1Input, but then
// we can't declare Foo() in the Base class.
return 0;
}
Since your Derived class is-a Base class, it should never tighten the base contract preconditions: if it has to behave like a Base, it should accept BaseInput allright. This is known as the Liskov Substitution Principle.
Although you can do runtime checking of your argument, you can never achieve a fully type-safe way of doing this: your compiler may be able to match the DerivedInput when it sees a Derived object (static type), but it can not know what subtype is going to be behind a Base object...
The requirements
DerivedX should take a DerivedXInput
DerivedX::Foo should be interface-equal to DerivedY::Foo
contradict: either the Foo methods are implemented in terms of the BaseInput, and thus have identical interfaces in all derived classes, or the DerivedXInput types differ, and they cannot have the same interface.
That's, in my opinion, the problem.
This problem occured to me, too, when writing tightly coupled classes that are handled in a type-unaware framework:
class Fruit {};
class FruitTree {
virtual Fruit* pick() = 0;
};
class FruitEater {
virtual void eat( Fruit* ) = 0;
};
class Banana : public Fruit {};
class BananaTree {
virtual Banana* pick() { return new Banana; }
};
class BananaEater : public FruitEater {
void eat( Fruit* f ){
assert( dynamic_cast<Banana*>(f)!=0 );
delete f;
}
};
And a framework:
struct FruitPipeLine {
FruitTree* tree;
FruitEater* eater;
void cycle(){
eater->eat( tree->pick() );
}
};
Now this proves a design that's too easily broken: there's no part in the design that aligns the trees with the eaters:
FruitPipeLine pipe = { new BananaTree, new LemonEater }; // compiles fine
pipe.cycle(); // crash, probably.
You may improve the cohesion of the design, and remove the need for virtual dispatching, by making it a template:
template<class F> class Tree {
F* pick(); // no implementation
};
template<class F> class Eater {
void eat( F* f ){ delete f; } // default implementation is possible
};
template<class F> PipeLine {
Tree<F> tree;
Eater<F> eater;
void cycle(){ eater.eat( tree.pick() ); }
};
The implementations are really template specializations:
template<> class Tree<Banana> {
Banana* pick(){ return new Banana; }
};
...
PipeLine<Banana> pipe; // can't be wrong
pipe.cycle(); // no typechecking needed.
You might be able to use a variation of the curiously recurring template pattern.
class Base {
public:
// Stuff that don't depend on the input type.
};
template <typename Input>
class Middle : public Base {
public:
virtual void Foo(Input &i) = 0;
};
class Derived1 : public Middle<Derived1Input> {
public:
virtual void Foo(Derived1Input &i) { ... }
};
class Derived2 : public Middle<Derived2Input> {
public:
virtual void Foo(Derived2Input &i) { ... }
};
This is untested, just a shot from the hip!
If you don't mind the dynamic cast, how about this:
Class BaseInput;
class Base
{
public:
void foo(BaseInput & x) { foo_dispatch(x); };
private:
virtual void foo_dispatch(BaseInput &) = 0;
};
template <typename TInput = BaseInput> // default value to enforce nothing
class FooDistpatch : public Base
{
virtual void foo_dispatch(BaseInput & x)
{
foo_impl(dynamic_cast<TInput &>(x));
}
virtual void foo_impl(TInput &) = 0;
};
class Derived1 : public FooDispatch<Der1Input>
{
virtual void foo_impl(Der1Input & x) { /* your implementation here */ }
};
That way, you've built the dynamic type checking into the intermediate class, and your clients only ever derive from FooDispatch<DerivedInput>.
What you are talking about are covariant argument types, and that is quite an uncommon feature in a language, as it breaks your contract: You promised to accept a base_input object because you inherit from base, but you want the compiler to reject all but a small subset of base_inputs...
It is much more common for programming languages to offer the opposite: contra-variant argument types, as the derived type will not only accept everything that it is bound to accept by the contract, but also other types.
At any rate, C++ does not offer contravariance in argument types either, only covariance in the return type.
C++ has a lot of dark areas, so it's hard to say any specific thing is undoable, but going from the dark areas I do know, without a cast, this cannot be done. The virtual function specified in the base class requires the argument type to remain the same in all the children.
I am sure a cast can be used in a non-painful way though, perhaps by giving the base class an Enum 'type' member that is uniquely set by the constructor of each possible child that might possibly inherit it. Foo() can then check that 'type' and determine which type it is before doing anything, and throwing an assertion if it is surprised by something unexpected. It isn't compile time, but it's the closest a compromise I can think of, while still having the benefits of requiring a Foo() be defined.
It's certainly restricted, but you can use/simulate coviarance in constructors parameters.
I need to initialize an object in a method without specifying the class from where the object is. Can I do that?
can someone give me an example?
EDIT:
MyClass{
...};
MySecondClass
{...
};
void method(*object); //how to write correct??
{..}
MyClass *x= new MyClass();
MySecondClass *y= new MySecondClass();
method(x);
method(y);
Use templates.
template <typename T>
void method(T* object) {
// do stuff with the object, whose real type will be substituted for `T`
}
Templates are a bit complex, so read the chapter in your C++ book on them for more information.
It sounds like you're looking for an interface. You would define an interface that fits the needs of whatever it is that your method is doing.
class MyInterface
{
public:
virtual void doSomething1() = 0;
virtual void doSomething2() = 0;
};
class MyObject : public MyInterface
{
public:
void doSomething1()
{
// Code here
}
void doSomething2()
{
// Code here
}
};
It's somewhat unclear exactly the situation you have b/c you haven't shown any code, but make the method you want to call part of a class. (if it isn't already)
class ClassWithMethod
{
public:
ClassWithMethod(MyInterface &myI)
:x(myI)
{
}
void methodYouUseInjectedObject()
{
// Code
x.doSomething1();
// More code
}
private:
MyInterface &x;
};
Then in you application code where you instantiate the ClassWithMethod, you would "inject" the concrete type of the object you want called.
int main(int argc, char *argv[])
{
MyObject myObject;
ClassWithMethod classMethod(myObject);
// Call the method that will use the injected object.
classMethod.methodYouUseInjectedObject();
return 1;
}
EDIT: (based on updated question)
If you want to create a method that can take two different (and unrelated) objects, but the use the same method signatures you can use a template.
class ClassWithMethod
{
public:
template <class T>
void methodYouUseInjectedObject(T object)
{
T.doSomething();
}
};
This is similar to my approach above except that you do not need to derive your different objects off an interface.
You can use a template.
template<typename T>
void method(T object) {
object.doSomething()
}
I have a class (class A) that is designed to be inherited by other classes written by other people.
I also have another class (class B), that also inherits from A.
B has to access some A's member functions that shouldn't be accessed by other inheriting classes.
So, these A's member functions should be public for B, but private for others.
How can I solve it without using 'friend' directive?
Thank you.
EDIT: Example why I need it.
class A
{
public:
void PublicFunc()
{
PrivateFunc();
// and other code
}
private:
virtual void PrivateFunc();
};
class B : public class A
{
private:
virtual void PrivateFunc()
{
//do something and call A's PrivateFunc
A::PrivateFunc(); // Can't, it's private!
}
};
You can't. That's what friend is for.
An alternative would be to change the design/architecture of your program. But for hints on this I'd need some more context.
What you say is: there are two sets of subclasses of A. One set should have access, the other set shouldn't. It feels wrong to have only one brand of subclasses (i.e. B) 'see' A's members.
If what you mean is: only we can use this part of functionality, while our clients can't, there are other resorts.
(Functionality reuse by inheritance often corners you with this kind of problems. If you go towards reuse by aggregation, you may get around it.)
A suggestion:
// separate the 'invisible' from the 'visible'.
class A_private_part {
protected:
int inherited_content();
public:
int public_interface();
};
class B_internal : public A_private_part {
};
class A_export : private A_private_part {
public:
int public_interface() { A_private_part::public_interface(); }
};
// client code
class ClientClass : public A_export {
};
But better would be to go the aggregation way, and split the current "A" into a visible and an invisible part:
class InvisibleFunctionality {
};
class VisibleFunctionality {
};
class B {
InvisibleFunctionality m_Invisible;
VisibleFunctionality m_Visible;
};
// client code uses VisibleFunctionality only
class ClientClass {
VisibleFunctionality m_Visible;
};
Well - if you want exactly what you've described, then friend is the best solution. Every coding standard recommends not using friend but where the alternative design is more complex - then maybe it's worth making an exception.
To solve the problem without friend will require a different architecture
One solution might be to use a form of the pImpl idiom where 'B' derives from the inner implementation object, while the other clients derive from the outer class.
Another might be to place an extra layer of inheritance between 'A' and the "other clients". Something like:
class A {
public:
void foo ();
void bar ();
};
class B : public A { // OK access to both 'foo' and 'bar'
};
class ARestricted : private A {
public:
inline void foo () { A::foo (); }; // Forwards 'foo' only
};
However, this solution still has it's problems. 'ARestricted' cannot convert to an 'A' so this would need to be solved by some other "getter" for 'A'. However, you could name this function in such a way as it cannot be called accidentally:
inline A & get_base_type_A_for_interface_usage_only () { return *this; }
After trying to think of other solutions, and assuming that your hierarchy needs to be as you describe, I recommend you just use friend!
EDIT: So xtofl suggested renaming the types 'A' to 'AInternal' and 'ARestricted' to 'A'.
That works, except I noticed that 'B' would no longer be an 'A'. However, AInternal could be inherited virtually - and then 'B' could derive from both 'AInternal' and 'A'!
class AInternal {
public:
void foo ();
void bar ();
};
class A : private virtual AInternal {
public:
inline void foo () { A::foo (); }; // Forwards 'foo' only
};
// OK access to both 'foo' and 'bar' via AInternal
class B : public virtual AInternal, public A {
public:
void useMembers ()
{
AInternal::foo ();
AInternal::bar ();
}
};
void func (A const &);
int main ()
{
A a;
func (a);
B b;
func (b);
}
Of course now you have virtual bases and multiple inheritance! Hmmm....now, is that better or worse than a single friend declaration?
I think you have a bigger problem here. Your design doesn't seem sound.
1) I think the 'friend' construct is problematic to begin with
2) if 'friend' isn't what you want, you need to re-examine your design.
I think you either need to do something that just gets the job done, using 'friend' or develop a more robust architecture. Take a look at some design patterns, I'm sure you'll find something useful.
EDIT:
After seeing your sample code, you definitely need to re-arch. Class A may not be under your control, so that's a little tricky, but maybe want you want to re-do Class B to be a "has-a" class instead of an "is-a" class.
public Class B
{
B()
{
}
void someFunc()
{
A a; //the private functions is now called and a will be deleted when it goes out of scope
}
};
I find this a interesting challenge. Here is how I would solve the problem:
class AProtectedInterface
{
public:
int m_pi1;
};
class B;
class A : private AProtectedInterface
{
public:
void GetAProtectedInterface(B& b_class);
int m_p1;
};
class B : public A
{
public:
B();
void SetAProtectedInterface(::AProtectedInterface& interface);
private:
::AProtectedInterface* m_AProtectedInterface;
};
class C : public A
{
public:
C();
};
C::C()
{
m_p1 = 0;
// m_pi1 = 0; // not accessible error
}
B::B()
{
GetAProtectedInterface(*this);
// use m_AProtectedInterface to get to restricted areas of A
m_p1 = 0;
m_AProtectedInterface->m_pi1 = 0;
}
void A::GetAProtectedInterface(B& b_class)
{
b_class.SetAProtectedInterface(*this);
}
void B::SetAProtectedInterface(::AProtectedInterface& interface)
{
m_AProtectedInterface = &interface;
}
If you where going to use this sort of pattern all the time, you could reduce the code by using templates.
template<class T, class I>
class ProtectedInterfaceAccess : public I
{
public:
void SetProtectedInterface(T& protected_interface)
{
m_ProtectedInterface = &protected_interface;
}
protected:
T& GetProtectedInterface()
{
return *m_ProtectedInterface;
}
private:
T* m_ProtectedInterface;
};
template<class T, class I>
class ProtectedInterface : private T
{
public:
void SetupProtectedInterface(I& access_class)
{
access_class.SetProtectedInterface(*this);
}
};
class Bt;
class At : public ProtectedInterface <::AProtectedInterface, Bt>
{
public:
int m_p1;
};
class Bt : public ProtectedInterfaceAccess<::AProtectedInterface, At>
{
public:
Bt();
};
class Ct : public At
{
public:
Ct();
};
Ct::Ct()
{
m_p1 = 0;
// m_pi1 = 0; // not accessible error
}
Bt::Bt()
{
SetupProtectedInterface(*this);
m_p1 = 0;
GetProtectedInterface().m_pi1 = 0;
}
If I understand:
A will be subclassed by other developers.
B will be subclassed by other developers and inherits from A.
A has some methods you don't want accessible to outside developers through B.
I don't think this can be done without using friend. There is no way I know of to make members of a superclass available only to direct inheritors.