C++ compile time type determination - c++

I have two classes deriving from the same base class. on compile time it is known which one gets created based on a macro define. I have another class that is a user and calls member functions (different ones for each class). It looks like this:
class User() {
void useClass( Base* p ) {
#ifdef useA
p->aFun();
#else
p->bFun()
#endif
}
class Base() {}
class A : public Base {
void aFun();
}
class B : public Base {
void bFun();
}
class C {
C() {
#ifdef useA
p = new A();
#else
p = new B();
#endif
}
Base* p;
User m_user;
void doStuffWithUser() {
user.useClass( p );
}
}
I would like to reduce the amount of macros, so I am wondering if there is a better way to do this. In particular, the #ifdef in the User class doesn't look very nice to me. Is there a way to reproduce it without using the macro? Ideally without runtime checks to determine what type p is.
EDIT:
The two derived classes have different members that need to be called and despite the inheritance, this cant be changed.

A solution is the visitor pattern.
The idea is to have two classes : the visitor and the visited.
The visitor is used to call a function depending on the real type of the object. The visited is the object of your class hierarchy.
In your example, you could do:
class User() {
void useClass( Base* p ) {
p->visit(visitor);
}
class Base() {
virtual void visit(Visitor) = 0;
}
class A : public Base {
void aFun();
virtual void visit(Visitor v) override {
v.visit(this);
}
}
class B : public Base {
void bFun();
virtual void visit(Visitor v) override {
v.visit(this);
}
}
class Visitor {
void visit(B* b) {
b->bFun();
}
void visit(A* a) {
a->aFun();
}
}
By having this double dispatch with the visit function, you ensure that you call the function depending on the real type.
I don't think there is a compile time solution to your issue because in useClass (as it is now), there is no way (at compile time) to know the real type of p. If you want to have a compile time solution you need to do more changes. For example making useClass a template or overloading it, which mean you can't call useClass with a Base* any more ...

The fact that A and B share a common base class is irrelevant since they have different interfaces that you are using.
I would make C a template and store a pointer to the derived class instead of the base class:
template<typename T>
class CT {
public:
CT() {
p = std::make_unique<T>();
}
std::unique_ptr<T> p;
User m_user;
void doStuffWithUser() {
user.useClass(p);
}
};
Then you can simply overload useClass() to accept either A or B:
class User {
public:
void useClass(A* p) {
p->aFun();
}
void useClass(B* p) {
p->bFun();
}
};
Now you just have one compile time switch:
#ifdef useA
using C = CT<A>;
#else
using C = CT<B>;
#endif

You can rename aFun and bFun to Fun and make it virtual(also add it in Base class) and in useClass, use Fun method, compiler will figure out which method to use.
This will eliminate first macro.
For the second maybe you should use rewrite it in some other way, so you wouldnt use macros at all. I don't think you can reproduce this behavior without macros.
Maybe you should have some flag that you give to constructor, 1 to create object A or 0 to create object B and get this flag from user at the runtime.
EDIT
So maybe you can create function Fun that in class A calls aFun and in class B calls bFun.

You can create a template for User class and specialize it for class A and class B:
template<typename T>
class User
{
void useClass( Base* p );
}
template<>
class User<A>
{
void useClass( Base* p ) {p->aFun();}
};
template<>
class User<B>
{
void useClass( Base* p ) {p->bFun();}
};
Now in class C:
template<typename T>
class C {
C() {
p = new T();
}
Base* p;
User<T> m_user;
void doStuffWithUser() {
m_user.useClass( p );
}
}
As a final note, just avoid using new operator. Try std::unique_ptr or std::shared_prt
PS. I have not tested this code

if you do not want to change any interface you can use single #ifdef
class Base {};
class A : public Base {
public:
void aFun(){}
};
class B : public Base {
public:
void bFun(){}
};
#ifdef useA
typedef A impl_type;
auto correct_func = &impl_type::aFun;
#else
typedef B impl_type;
auto correct_func = &impl_type::bFun;
#endif
class User {
public:
void useClass( Base* p ) {
auto pointer = (static_cast<impl_type*>(p));
(pointer->*correct_func)();
}
};
class C {
C() {
p = new impl_type();
}
Base* p;
User m_user;
void doStuffWithUser() {
m_user.useClass( p );
}
};

Probably you could name both functions with the same name in A and B and make it virtual, so useClass will call only needed function.
Like
class User() {
void useClass( Base* p ) {
p->fun();
}
};
class Base() {
virtual void fun() = 0;
};
class A : public Base {
void fun();
};
class B : public Base {
void fun();
};
Also you can use some kind of constexpr function (if you are using c++11 standard or newer) to determine what type p is.
Edit:
After seeing comment, i think that you're probably can left yours aFun(), bFun(), and just add some fun() func which will be derived and call type-specific function.
Also, it may be helpful to try and create some adapter classes with same interfaces(as in gof patterns).
Edit2: I mean that there could be some function like
constexpr Base* chooseType(int a){
if(a == 0){
return new A();
} else {
return new B();
}
}
/////
C() {
int case = 0;
p = chooseType(case);
}
And it will be called in compile-time, so as choice of class.

If you can't change the interface, want to get rid of #ifdefs, and have compile-time guarantee of types being used, without run-time checks - I would suggest using combination of templates, and overloaded functions.
First of all, I would change class C to be a template:
template<typename Type>
class C
{
static_assert(std::is_base_of<Base, Type>::value, "Template argument of C is not base of Base!");
public:
C () {p = new Type;}
~C() {delete p;}
void fun () {u.useClass (p);}
private:
Type* p;
User u;
};
And, then would change User class to switch between different possible implementations of Base with overloaded functions:
class User
{
public:
void useClass (A* p) {p->aFun();}
void useClass (B* p) {p->bFun();}
};
And, then you would create object of C as follows:
C<A> ca;
If you forgot to implement type-specific useClass, or tried to use wrong type in C (i.e. not inherited from Base), you would get compile-time errors.
In addition, if some of the child classes of Base, that you want to switch between, have non-default constructors, you may pass a functor (e.g. std::function<Type*()>) to a C constructor, and use that to create an object.
Such a constructor may look like:
C (std::function<Type* ()> function) {p = function();}
And usage of it would look like:
C<Z> cz ([&]{return new Z(someInt);});

Related

A function overload depending on enum

Sorry for the noob question, but I cannot seem to get my head around C++'s static nature. The problem: I have a class that returns an enum and depending on it I have to convert the said class using another class and return a vector. In code:
enum TYPES { TYPE_A, TYPE_B, TYPE C }
class A {
TYPES getType() {}
}
class B : public A {}
class C : public A {}
class D : public A {}
std::vector<?> convert_to_vector(const A& a) {
// depending on what enum is returned by a.getType()
// I have to convert a into B, C, or D class and return std::vector of
// an appropriate type, e.g. int for B, float for C, etc.
}
int main() {
A a;
auto v = convert_to_vector(a);
}
The simplest way would be using switch(a.getType()) but I have different return types in each case and using auto as the return type doesn't work. I have tried templates and template specification, but they don't accept the runtime variable that is return by a.getType(). I guess there must be some simple solution that I'm overlooking here, but I have run out of ideas at this point and would be grateful for any pointers.
Thanks!
You can't change the return type of a C++ function at runtime. But you can use a variant type:
std::variant<std::vector<int>, std::vector<float>> convert_to_vector(const A& a) {
if (a.getType() == TYPE_B)
return std::vector<int>();
if (a.getType() == TYPE_C)
return std::vector<float>();
throw std::logic_error("unsupported type");
}
If you don't have C++17, you can use boost::variant instead of std::variant.
I think instead of deciding the type of a vector on an enum a much better solution would be to have a parent class A which can have a vector inside it which is based on a template variable. In your classes B, C, D you can simply inherit A and specify a template type. So, when you create a new object for B, C, D you will already have a vector member for those objects. You can also have a virtual function convertToVec which you can override in the child classes depending on how you want to convert data into a vector.
template<class T>
class A {
std::vector<T> vec;
std::vector<T> GetVector() { return vec; }
virtual convertToVec() { .... }
}
class B : public A<bool> {}
class C : public A<float> {}
class D : public A<long long int> {}
int main() {
B b;
b.GetVector();
//A* b = new B();
//b->convertToVec();
}
While it's pretty hard to follow what exactly you are trying to achieve here, going to use switch-case is not a good idea, instead you'd better to leverage polymorphism. For example:
class A {
public:
virtual void convertToVector(AuxVectorConverter& aux) = 0;
};
class B {
public:
// Add here specific implementation
virtual void convertToVector(AuxVectorConverter& aux) {
aux.convertToVectorB(this);
}
};
class C {
public:
// Add here specific implementation
virtual void convertToVector(AuxVectorConverter& aux) {
aux.doSomethingC(this);
}
};
// Aux class
class AuxVectorConverter {
public:
convertToVector(A* a) {
a->convertToVector(this);
}
convertToVectorB(B* b) {
// Do code specific for B
}
convertToVectorC(C* c) {
// Do code specific for B
}
}
int main() {
AuxVectorConverter* aux;
A* a = ...; // Initialize here either with instance of B or C
// Now, based on run time aux class will issue appropriate method.
aux.convertToVector(a);
}
You might find more details here
UPDATE (Based on comment)
An alternative approach could be to define a map from TYPES to some abstract class which will align with the patter from above, e.g.:
// Map has to be initialized with proper implementation
// of action according to type
map<Types, AbstracatAction> actions;
// Latter in the code you can do:
aux.convertToVector(actions[a->getType()]);
And action will be defined pretty similar to hierarchy I've showed above, e.g.
class AbstractAction {
public:
virtual void convertToVector(AuxVectorConverter& aux) = 0;
};
class ActionB: public AbstractAction {
public:
virtual void convertToVector(AuxVectorConverter& aux) {
aux.covertToVectorB(this);
}
};

Grouping two types together

I use a third party library over which I have no control. It contains 2 classes A and B, which both define a method with the same name:
class A {
public:
...
void my_method ();
};
class B {
public:
...
void my_method ();
};
I want to create a class C that contains a member which is of class A or B. Crucially, I can know only at runtime whether I will need A or B. This class C will only call the method my_method.
If I could modify the code, I would simply make A and B derive from a parent class (interface) that defined my_method. But I can't.
What is the simplest/most elegant way to create this class C? I could of course define C in this way:
class C {
public:
void call_my_method() { if (a) a->my_method() else b->my_method(); }
private:
A* a;
B* b;
But I want to avoid paying the cost of the if statement everytime. It also feels inelegant. Is there a way I can create a super type of class A or B? Or any other solution to this problem?
You may use std::function (not sure it has better performance though), something like:
class C {
public:
void call_my_method() { my_method(); }
void use_a(A* a) { my_method = [=]() { a->my_method() }; }
void use_b(B* b) { my_method = [=]() { b->my_method() }; }
private:
std::function<void()> my_method;
};
No; at some point you need branching. The best you can do is to hoist the branching up/down the call stack†, so that more of your program is encapsulated within the figurative if/else construct and the branch itself need be performed less frequently. Of course then you need to duplicate more of your program's source code, which is not ideal.
The only improvement I'd suggest at this time is a construct such as boost::variant. It basically does what you're already doing, but takes up less memory and doesn't have that layer of indirection (using what's called a tagged union instead). It still needs to branch on access, but until profiling has revealed that this is a big bottleneck (and you'll probably find that branch prediction alleviates much of this risk) I wouldn't go any further with your changes.&ddagger;
† I can never remember which way it goes lol
&ddagger; One such change might be to conditionally initialise a function pointer (or modern std::function), then call the function each time. However, that's a lot of indirection. You should profile, but I'd expect it to be slower and harder on the caches. An OO purist might recommend a polymorphic inheritance tree and virtual dispatch, but that's not going to be of any use to you once you care about performance this much.
How about using inheritance with a virtual function, using a 'base class' (C):
class C
{
public:
virtual void do_method() = 0;
};
class D : public C, private A
{
void do_method() { my_method(); }
};
class E : public C, private B
{
void do_method() { my_method(); }
}
Then this will work:
C * d = new D();
d->do_method();
Suggest to wrap your A and B objects into some helper template TProxy which realizes IProxy interface. Class C (or Consumer) will work with IProxy interface and won't know about type of the object inside Proxy
#include <stdio.h>
struct A {
void func () { printf("A::func\n"); }
};
struct B {
void func () { printf("B::func\n"); }
};
struct IProxy
{
virtual void doFunc() = 0;
virtual ~IProxy() {};
};
template<typename T>
struct TProxy : public IProxy
{
TProxy(T& i_obj) : m_obj(i_obj) { }
virtual void doFunc() override { m_obj.func(); }
private:
T& m_obj;
};
class Consumer
{
public:
Consumer(IProxy& i_proxy) : m_proxy(i_proxy) {}
void Func() { m_proxy.doFunc();}
private:
IProxy& m_proxy;
};
Main:
int main()
{
A a;
TProxy<A> aProxy(a);
B b;
TProxy<B> bProxy(b);
Consumer consumerA{aProxy};
consumerA.Func();
Consumer consumerB{bProxy};
consumerB.Func();
return 0;
}
Output:
A::func
B::func

c++ overriding a function only for a specific instance

I was wondering whether there's a way to override a function for a specific instance only. For ex,
class A
{
public:
...
void update();
...
}
int main()
{
...
A *first_instance = new A();
// I want this to have a specific update() function.
// ex. void update() { functionA(); functionB(); ... }
A *second_instance = new A();
// I want this to have a different update() function than the above one.
// ex. void update() { functionZ(); functionY(); ...}
A *third_instance = new A();
// ....so on.
...
}
Is there a way to achieve this?
I think virtual function is just what you want, with virtual function, different instances of the same type can have different functions, but you need to inherit the base class. for example
class A
{
public:
...
virtual void update()
{
std::cout << "Class A\n";
}
...
};
class B: public A
{
public:
virtual void update()
{
std::cout << "Class B\n";
}
};
class C: public A
{
public:
virtual void update()
{
std::cout << "Class C\n";
}
};
int main()
{
...
A *first_instance = new A();
// I want this to have a specific update() function.
// ex. void update() { functionA(); functionB(); ... }
A *second_instance = new B();
// I want this to have a different update() function than the above one.
// ex. void update() { functionZ(); functionY(); ...}
A *third_instance = new C();
// ....so on.
...
}
each instance in the above code will bind different update functions.
Besides, you can also use function pointer to implement your requirement, but it is not recommended. For example
class A
{
public:
A(void(*u)())
{
this->update = u;
}
...
void (*update)();
};
void a_update()
{
std::cout << "update A\n";
}
void b_update()
{
std::cout << "update B\n";
}
void c_update()
{
std::cout << "update C\n";
}
int main()
{
...
A first_instance(a_update);
// I want this to have a specific update() function.
// ex. void update() { functionA(); functionB(); ... }
A second_instance(b_update);
// I want this to have a different update() function than the above one.
// ex. void update() { functionZ(); functionY(); ...}
A third_instance(c_update);
// ....so on.
...
}
Hope helps!
Hold a function in the class.
#include <iostream>
#include <functional>
using namespace std;
class Foo
{
public:
Foo(const function<void ()>& f) : func(f)
{
}
void callFunc()
{
func();
}
private:
function<void ()> func;
};
void printFoo() { cout<<"foo"<<endl; }
void printBar() { cout<<"bar"<<endl; }
int main()
{
Foo a(printFoo);
Foo b(printBar);
a.callFunc();
b.callFunc();
}
You may have noticed that the end brace of a class is often followed by a semicolon, whereas the end braces of functions, while loops etc don't. There's a reason for this, which relates to a feature of struct in C. Because a class is almost identical to a struct, this feature exists for C++ classes too.
Basically, a struct in C may declare a named instance instead of (or as well as) a named "type" (scare quotes because a struct type in C isn't a valid type name in itself). A C++ class can therefore do the same thing, though AFAIK there may be severe limitations on what else that class can do.
I'm not in a position to check at the moment, and it's certainly not something I remember using, but that may mean you can declare a named class instance inheriting from a base class without giving it a class name. There will still be a derived type, but it will be anonymous.
If valid at all, it should look something like...
class : public baseclass // note - no derived class name
{
public:
virtual funcname ()
{
...
}
} instancename;
Personally, even if this is valid, I'd avoid using it for a number of reasons. For example, the lack of a class name means that it's not possible to define member functions separately. That means that the whole class declaration and definition must go where you want the instance declared - a lot of clutter to drop in the middle of a function, or even in a list of global variables.
With no class name, there's presumably no way to declare a constructor or destructor. And if you have non-default constructors from the base class, AFAIK there's no way to specify constructor parameters with this.
And as I said, I haven't checked this - that syntax may well be illegal as well as ugly.
Some more practical approaches to varying behaviour per-instance include...
Using dependency injection - e.g. providing a function pointer or class instance (or lambda) for some part of the behavior as a constructor parameter.
Using a template class - effectively compile-time dependency injection, with the dependency provided as a function parameter to the template.
I think it will be the best if you'll tell us why do you need to override a function for a specific instance.
But here's another approach: Strategy pattern.
Your class need a member that represent some behaviour. So you're creating some abstract class that will be an interface for different behaviours, then you'll implement different behaviours in subclasses of that abstract class. So you can choose those behaviours for any object at any time.
class A;//forward declaration
class Updater
{
public:
virtual ~Updater() {};//don't forget about virtual destructor, though it's not needed in this case of class containing only one function
virtual void update(A&) = 0;
}
class SomeUpdater
{
public:
virtual void update(A & a);//concrete realisation of an update() method
}
class A
{
private:
Updater mUpdater;
public:
explicit A(Updater updater);//constructor takes an updater, let's pretend we want to choose a behaviour once for a lifetime of an object - at creation
void update()
{
mUpdater.update(this);
}
}
You can use local classes, yet, personally, I consider the "hold function in the class" approach mentioned in the other answer better. I'd recommend the following approach only if doFunc must access internals of your base class, which is not possible from a function held in a member variable:
class ABase {
public:
void Func () { this->doFunc (); }
private:
virtual void doFunc () = 0;
public:
virtual ~ABase () { }
};
ABase* makeFirstA () {
class MyA : public ABase {
virtual void doFunc () { std::cout << "First A"; }
};
return new MyA;
}
ABase* makeSecondA () {
class MyA : public ABase {
virtual void doFunc () { std::cout << "Second A"; }
};
return new MyA;
}
int main () {
std::shared_ptr<ABase> first (makeFirstA ());
std::shared_ptr<ABase> second (makeSecondA ());
first->Func ();
second->Func ();
}
From a design patterns point of view, the "local classes" approach implements the template method pattern, while the "hold a function(al) in a member variable" approach reflects the strategy pattern. Which one is more appropriate depends on what you need to achieve.

How can I use covariant return types with smart pointers?

I have code like this:
class RetInterface {...}
class Ret1: public RetInterface {...}
class AInterface
{
public:
virtual boost::shared_ptr<RetInterface> get_r() const = 0;
...
};
class A1: public AInterface
{
public:
boost::shared_ptr<Ret1> get_r() const {...}
...
};
This code does not compile.
In visual studio it raises
C2555: overriding virtual function return type differs and is not
covariant
If I do not use boost::shared_ptr but return raw pointers, the code compiles (I understand this is due to covariant return types in C++). I can see the problem is because boost::shared_ptr of Ret1 is not derived from boost::shared_ptr of RetInterface. But I want to return boost::shared_ptr of Ret1 for use in other classes, else I must cast the returned value after the return.
Am I doing something wrong?
If not, why is the language like this - it should be extensible to handle conversion between smart pointers in this scenario? Is there a desirable workaround?
Firstly, this is indeed how it works in C++: the return type of a virtual function in a derived class must be the same as in the base class. There is the special exception that a function that returns a reference/pointer to some class X can be overridden by a function that returns a reference/pointer to a class that derives from X, but as you note this doesn't allow for smart pointers (such as shared_ptr), just for plain pointers.
If your interface RetInterface is sufficiently comprehensive, then you won't need to know the actual returned type in the calling code. In general it doesn't make sense anyway: the reason get_r is a virtual function in the first place is because you will be calling it through a pointer or reference to the base class AInterface, in which case you can't know what type the derived class would return. If you are calling this with an actual A1 reference, you can just create a separate get_r1 function in A1 that does what you need.
class A1: public AInterface
{
public:
boost::shared_ptr<RetInterface> get_r() const
{
return get_r1();
}
boost::shared_ptr<Ret1> get_r1() const {...}
...
};
Alternatively, you can use the visitor pattern or something like my Dynamic Double Dispatch technique to pass a callback in to the returned object which can then invoke the callback with the correct type.
There is a neat solution posted in this blog post (from Raoul Borges)
An excerpt of the bit prior to adding support for mulitple inheritance and abstract methods is:
template <typename Derived, typename Base>
class clone_inherit<Derived, Base> : public Base
{
public:
std::unique_ptr<Derived> clone() const
{
return std::unique_ptr<Derived>(static_cast<Derived *>(this->clone_impl()));
}
private:
virtual clone_inherit * clone_impl() const override
{
return new Derived(*this);
}
};
class concrete: public clone_inherit<concrete, cloneable>
{
};
int main()
{
std::unique_ptr<concrete> c = std::make_unique<concrete>();
std::unique_ptr<concrete> cc = c->clone();
cloneable * p = c.get();
std::unique_ptr<clonable> pp = p->clone();
}
I would encourage reading the full article. Its simply written and well explained.
You can't change return types (for non-pointer, non-reference return types) when overloading methods in C++. A1::get_r must return a boost::shared_ptr<RetInterface>.
Anthony Williams has a nice comprehensive answer.
What about this solution:
template<typename Derived, typename Base>
class SharedCovariant : public shared_ptr<Base>
{
public:
typedef Base BaseOf;
SharedCovariant(shared_ptr<Base> & container) :
shared_ptr<Base>(container)
{
}
shared_ptr<Derived> operator ->()
{
return boost::dynamic_pointer_cast<Derived>(*this);
}
};
e.g:
struct A {};
struct B : A {};
struct Test
{
shared_ptr<A> get() {return a_; }
shared_ptr<A> a_;
};
typedef SharedCovariant<B,A> SharedBFromA;
struct TestDerived : Test
{
SharedBFromA get() { return a_; }
};
Here is my attempt :
template<class T>
class Child : public T
{
public:
typedef T Parent;
};
template<typename _T>
class has_parent
{
private:
typedef char One;
typedef struct { char array[2]; } Two;
template<typename _C>
static One test(typename _C::Parent *);
template<typename _C>
static Two test(...);
public:
enum { value = (sizeof(test<_T>(nullptr)) == sizeof(One)) };
};
class A
{
public :
virtual void print() = 0;
};
class B : public Child<A>
{
public:
void print() override
{
printf("toto \n");
}
};
template<class T, bool hasParent = has_parent<T>::value>
class ICovariantSharedPtr;
template<class T>
class ICovariantSharedPtr<T, true> : public ICovariantSharedPtr<typename T::Parent>
{
public:
T * get() override = 0;
};
template<class T>
class ICovariantSharedPtr<T, false>
{
public:
virtual T * get() = 0;
};
template<class T>
class CovariantSharedPtr : public ICovariantSharedPtr<T>
{
public:
CovariantSharedPtr(){}
CovariantSharedPtr(std::shared_ptr<T> a_ptr) : m_ptr(std::move(a_ptr)){}
T * get() final
{
return m_ptr.get();
}
private:
std::shared_ptr<T> m_ptr;
};
And a little example :
class UseA
{
public:
virtual ICovariantSharedPtr<A> & GetPtr() = 0;
};
class UseB : public UseA
{
public:
CovariantSharedPtr<B> & GetPtr() final
{
return m_ptrB;
}
private:
CovariantSharedPtr<B> m_ptrB = std::make_shared<B>();
};
int _tmain(int argc, _TCHAR* argv[])
{
UseB b;
UseA & a = b;
a.GetPtr().get()->print();
}
Explanations :
This solution implies meta-progamming and to modify the classes used in covariant smart pointers.
The simple template struct Child is here to bind the type Parent and inheritance. Any class inheriting from Child<T> will inherit from T and define T as Parent. The classes used in covariant smart pointers needs this type to be defined.
The class has_parent is used to detect at compile time if a class defines the type Parent or not. This part is not mine, I used the same code as to detect if a method exists (see here)
As we want covariance with smart pointers, we want our smart pointers to mimic the existing class architecture. It's easier to explain how it works in the example.
When a CovariantSharedPtr<B> is defined, it inherits from ICovariantSharedPtr<B>, which is interpreted as ICovariantSharedPtr<B, has_parent<B>::value>. As B inherits from Child<A>, has_parent<B>::value is true, so ICovariantSharedPtr<B> is ICovariantSharedPtr<B, true> and inherits from ICovariantSharedPtr<B::Parent> which is ICovariantSharedPtr<A>. As A has no Parent defined, has_parent<A>::value is false, ICovariantSharedPtr<A> is ICovariantSharedPtr<A, false> and inherits from nothing.
The main point is as Binherits from A, we have ICovariantSharedPtr<B>inheriting from ICovariantSharedPtr<A>. So any method returning a pointer or a reference on ICovariantSharedPtr<A> can be overloaded by a method returning the same on ICovariantSharedPtr<B>.
Mr Fooz answered part 1 of your question. Part 2, it works this way because the compiler doesn't know if it will be calling AInterface::get_r or A1::get_r at compile time - it needs to know what return value it's going to get, so it insists on both methods returning the same type. This is part of the C++ specification.
For the workaround, if A1::get_r returns a pointer to RetInterface, the virtual methods in RetInterface will still work as expected, and the proper object will be deleted when the pointer is destroyed. There's no need for different return types.
maybe you could use an out parameter to get around "covariance with returned boost shared_ptrs.
void get_r_to(boost::shared_ptr<RetInterface>& ) ...
since I suspect a caller can drop in a more refined shared_ptr type as argument.

Public and private access for the same member functions

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.