Is it possible, to somehow allow parent to access child protected members?
template <class T>
class B {
public :
void print()
{
cout << T::a << T::b << endl;
}
};
class C : public B<C>
{
protected :
static int a;
static int b;
public :
C() {
print();
}
};
This will be useful for me to inherit multiple objects without polymorphism(virtual). Any suggestgions??
Edit:
I find two solutions as suggested below ::
make the B as a friend class,
CRTP
Few more points to consider, while using CRTP make sure you use inline other wise it won't make it any faster(but code bloat may happen). Do not forget to make the B constructor protected(in case of static derived data access).
CRTP can also be used to not transfer static constant data(virtual static const) from base class to derived
The modern compilers use a concept called devirtualization i think it is in most compilers now.
This will be useful for me to inherit multiple objects without polymorphism(virtual).
It's a well known pattern and aka named static polymorphism.
The CRTP uses static_cast<T*>(this) to reference the derived class functions usually:
template <class T>
class B {
public :
void print()
{
cout << static_cast<T*>(this)->a << static_cast<T*>(this)->b << endl;
// ^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
}
};
I need to somehow allow parent to access child protected data, is it possible?
Of course it is possible. These need to be public members of T, or you need to make B<T> a friend class of T:
class C : public B<C>
{
friend class B<C>;
// ^^^^^^^^^^^^^^^^^^
protected :
static int a;
static int b;
public :
C() {
print();
}
};
Live Demo
The friend declaration still preserves the encapsulation of class C, while opening access to a specific interface declared in class B<T>.
Related
I have the following class
class A {
private:
B b;
public:
A();
}
class B {
public:
void foo();
void bar();
void foz();
........
}
B has a lot of methods. Sometimes is needed for a "customer" of class A to use method of class B. I could return a reference of B, but in this case I should return a const reference because returning a non-const reference of a private object is not good programming. If the reference is const, foo, bar and so on can't be called because they aren't const. So the only "clean" way seems to recreate the same interfaces in A using delegation to B. But this approach is not really good because I should recreate all the interfaces in A. As alternative I could set B as public in A, but it seems "strange" to me. What should I do in this case?
That is mainly an encapsulation question, and what you want to advertise in the public interface of class A.
If class B is also a public class - read can normally be used by users of class A and not a class internal to a library or framework - and if you want the existence of a B subobject to exist in the public documentation of class A and if you want to allow any operation on the B object, you can safely provide a getter.
If any of the above conditions is false, then the getter would break encapsulation and you would better define delegating methods in class A.
Depending on the general design, it could make sense to declare an interface class (say C) with only the methods that you want to allow from class A, and have B a subclass from C. Then you could safely declare a getter returning a reference on a C object:
class C {
public:
void foo(); // optionally virtual or pure virtual...
void bar();
void foz();
};
class B: public C {
.... // other members not relevant for what is public for A users
};
class A {
private:
B b;
public:
A();
C& getB() {
return b;
}
};
Solution 1. You create a getb() and return reference to B. Its not bad programming in you case particularly.
Solution 2. Create interface function for each corresponding function of b and call them.
void A::foo()
{
b.foo();
}
You can make the data member protectedinstead of private. Documentation says that protected members are not as private as private members, which are accessible only to members of the class in which they are declared, but they are not as public as public members, which are accessible in any function. protectedmembers (be they data members of method members) serve the role you're looking for : they are not accessible from everywhere (safe coding practices), but you can still manage them in clean ways when it makes sense :
If class A has an attribute of type B, is has access to B's
protected and publicmembers
friendfunctions can access both protected and publicmembers of a class they are friend with.
When preceding the name of a base class, the protected keyword specifies that the public and protected members of the base class are protected members of its derived classes.
Here, you're interested by the first item of the list : you can access B' methods from A; BUT B has still safeguards.
When I run the following code (adapted from your code) :
#include <iostream>
using std::cout;
using std::endl;
class B {
public:
void foo() { cout << "foo" << endl; };
void bar() { cout << "bar" << endl; };
void foz() { cout << "foz" << endl; };
};
class A {
protected: // <===== THIS IS THE SIGNIFICANT BIT
B b;
public:
A() {
b.foo();
b.bar();
b.foz();
cout << "A constructor" << endl;
};
};
int main(int argc, char** argv) {
A myA;
return 0;
}
I get the following console output :
foo
bar
foz
A constructor
Which shows that I can access B's methods from A.
I want to use a static member in a template class to instantiate a singleton object for each class that inherits from that template class.
Here is an example:
#include <iostream>
#include <vector>
struct X{
static std::vector<X*>& getRegistry(){
static std::vector<X*> registry;
return registry;
}
X(){
getRegistry().push_back(this); // Each X adds itself to the registry
}
};
template<typename T>
struct Y : X{
private:
static T instance; // The per-type singleton
};
template<typename T>
T Y<T>::instance {};
The idea is that objects of type X enter themselves into a "registry" whenever they are created. Class Y<T> that is derived from X is a template class that should instantiate a static singleton object of each type that inherits from it (using the curiously recurring template pattern).
The idea is that the "registry" will contain one object of each class that inherits from Y<T>. These classes should not have to do anything to get added to the registry; instead, simply inheriting from Y<T> should be enough to create a singleton object that is added to the registry.
I tried my code like this:
struct A : Y<A>{};
struct B : Y<B>{};
struct C : Y<C>{};
int main(){
std::cout << "Number of objects in the registry: " << X::getRegistry().size() << std::endl;
// Should print "3"
}
Fiddle link: http://ideone.com/aWDEg4
The desired behaviour should be that one A, one B, and one C, should be in the registry. But none of them is. The problem is that Y<T>::instance is not instantiated for any of the classes as it is not used in the code. However, I never want to use these fields, they are just their to instantiate the singleton. So is there a way to force the instantiation of the static field without having to add additional code to the deriving classes (i.e., A,B, and C)?
I know I can explicitly instantiate template class Y<A>;, but this would add additional code to the deriving class A.
You could just create static instances:
struct A : Y<A>{};
struct B : Y<B>{};
struct C : Y<C>{};
static A a;
static B b;
static C c;
int main(){
std::cout << "Number of objects in the registry: " << X::getRegistry().size() << std::endl;
}
output:
Number of objects in the registry: 3
I don't think you can avoid involving the clients of Y, but you can make Y's constructor private forcing client involvement. For example, this works as you want:
template<typename T>
struct Y : X {
Y(const Y<T> &other) {}
static Y<T> create() { &instance; return Y<T>(); }
private:
static T instance; // The per-type singleton
Y() {}
};
template<typename T>
T Y<T>::instance {};
struct A : Y<A> { A() : Y(Y::create()) {} };
struct B : Y<B> { B() : Y(Y::create()) {} };
struct C : Y<C> { C() : Y(Y::create()) {} };
The client involvement is the invocation of Y::create which also happens to force the instantiation of the instance member. Granted, this is probably not what you wanted, but it does work. Note also, my previous comment about the this pointer will still apply even if you can add the static instances to your registry.
class A {
public:
void fa() {
}
};
class B : public A{
public:
void fb() {
}
};
class C : public A, public B {
public:
void fc() {
//call A::fa(), not B::A::fa();
}
};
How to call A::fa() from C::fc() function.
GCC warns withdirect base A inaccessible in C due to ambiguity, does this mean there is no direct way to refer base class members?
One option would be to create a stub class that you can use for casting to the right base class subobject:
struct A {
void fa() { }
};
struct B : A {
void fb() { }
};
// Use a stub class that we can cast through:
struct A_ : A { };
struct C : A_, B {
void fc() {
implicit_cast<A_&>(*this).fa();
}
};
Where implicit_cast is defined as:
template <typename T> struct identity { typedef T type; }
template <typename T>
T implicit_cast(typename identity<T>::type& x) { return x; }
I just found the following info from ISO C++ 2003 standard (10.1.3)
A class shall not be specified as a direct base class of a derived class more than once. [Note: a class can be
an indirect base class more than once and can be a direct and an indirect base class. There are limited
things that can be done with such a class. The non-static data members and member functions of the direct
base class cannot be referred to in the scope of the derived class. However, the static members, enumerations
and types can be unambiguously referred to.
It means there is no direct way :(
I just compiled you code on codepad.org , putting A::fa() is enough to call fa() from your C::fc() function.
void fc() {
A::fa();
}
The below is the link to codepad with your code.
http://codepad.org/NMFTFRnt
I don't think you can do what you want. There is an ambiguity here: when you say A::fa(), it still doesn't tell the compiler which A object to use. There isn't any way to access class A. That's what the warning is telling you.
This seems like an awfully strange construct, though. Public inheritance should be used for is-a relationships. You are saying that C is-a A twice over? It doesn't make sense. And that suggests that this is either an artificial example that would never come up in practice, or you should reconsider this design.
You can use virtual inheritance to overcome such problem:
class B : virtual public A {
Now, you can use A::fa() simply in the child class C.
void fc()
{
fa();
}
However, I generally don't see any practical need to inherit class A again into class C, when B is already publically inheriting A. So, In your case, you can make it simple:
class C : public B {
Edit:
If you want 2 instances for A. then the direct instance which you are intending can be made as an object of C:
class C : public B {
A obj;
Because, having a directly inherited A will not be usable in anyway. You cannot declare any pointer or reference to it inside the scope of C.
for a certain project I have declared an interface (a class with only pure virtual functions) and want to offer users some implementations of this interface.
I want users to have great flexibility, so I offer partial implementations of this interface. In every implementation there is some functionality included, other functions are not overridden since they take care about different parts.
However, I also want to present users with a fully usable implementation of the interface as well. So my first approach was to simply derive a class from both partial implementations. This did not work and exited with the error that some functions are still pure virtual in the derived class.
So my question is if there is any way to simply merge two partial implementations of the same interface. I found a workaround by explicitely stating which function I want to be called for each method, but I consider this pretty ugly and would be grateful for an mechanism taking care of this for me.
#include <iostream>
class A{
public:
virtual void foo() = 0;
virtual void bar() = 0;
};
class B: public A{
public:
void foo(){ std::cout << "Foo from B" << std::endl; }
};
class C: public A{
public:
void bar(){ std::cout << "Bar from C" << std::endl; }
};
// Does not work
class D: public B, public C {};
// Does work, but is ugly
class D: public B, public C {
public:
void foo(){ B::foo(); }
void bar(){ C::bar(); }
};
int main(int argc, char** argv){
D d;
d.foo();
d.bar();
}
Regards,
Alexander
The actual problem is about managing several visitors for a tree, letting each of them traverse the tree, make a decision for each of the nodes and then aggregate each visitor's decision and accumulate it into a definite decision.
A separation of both parts is sadly not possible without (I think) massive overhead, since I want to provide one implementation taking care of managing the visitors and one taking care of how to store the final decision.
Have you considered avoiding the diamond inheritance completely, providing several abstract classes each with optional implementations, allowing the user to mix and match default implementation and interface as needed?
In your case what's happening is that once you inherit to D, B::bar hasn't been implemented and C::foo hasn't been implemented. The intermediate classes B and C aren't able to see each others' implementations.
If you need the full interface in the grandparent, have you considered providing the implementation in a different way, possibly a policy with templates, and default classes that will be dispatched into to provide the default behavior?
If your top level interface has a logical division in functionality, you should split it into two separate interfaces. For example if you have both serialization and drawing functions in interface A, you should separate these into two interfaces, ISerialization and IDrawing.
You're free to then provide a default implementation of each of these interfaces. The user of your classes can inherit either your interface or your default implementation as needed.
There is also the possibility that you could use a "factory" class for the main interface type. In other words the primary interface class also contains some type of static function that generates an appropriate child class on-request from the user. For instance:
#include <cstdio>
class A
{
public:
enum class_t { CLASS_B, CLASS_C };
static A* make_a_class(class_t type);
virtual void foo() = 0;
virtual void bar() = 0;
};
class B: public A
{
private:
virtual void foo() { /* does nothing */ }
public:
virtual void bar() { printf("Called B::bar()\n"); }
};
class C: public A
{
private:
virtual void bar() { /* does nothing */ }
public:
virtual void foo() { printf("Called C::foo()\n"); }
};
A* A::make_a_class(class_t type)
{
switch(type)
{
case CLASS_B: return new B();
case CLASS_C: return new C();
default: return NULL;
}
}
int main()
{
B* Class_B_Obj = static_cast<B*>(A::make_a_class(A::CLASS_B));
C* Class_C_Obj = static_cast<C*>(A::make_a_class(A::CLASS_C));
//Class_B_Obj->foo(); //can't access since it's private
Class_B_Obj->bar();
Class_C_Obj->foo();
//Class_C_Obj->bar(); //can't access since it's private
return 0;
}
If class A for some reason needs to access some private members of class B or class C, just make class A a friend of the children classes (for instance, you could make the constructors of class B and class C private constructors so that only the static function in class A can generate them, and the user can't make one on their own without calling the static factory function in class A).
Hope this helps,
Jason
Since you mentioned that you mainly needed access to the functions rather than data-members, here is another method you could use rather than multiple inheritance using templates and template partial specialization:
#include <iostream>
using namespace std;
enum class_t { CLASS_A, CLASS_B, CLASS_C };
template<class_t class_type>
class base_type
{
public:
static void foo() {}
static void bar() {}
};
template<>
void base_type<CLASS_A>::foo() { cout << "Calling CLASS_A type foo()" << endl; }
template<>
void base_type<CLASS_B>::bar() { cout << "Calling CLASS_B type bar()" << endl; }
template<>
void base_type<CLASS_C>::foo() { base_type<CLASS_A>::foo(); }
template<>
void base_type<CLASS_C>::bar() { base_type<CLASS_B>::bar(); }
int main()
{
base_type<CLASS_A> Class_A;
Class_A.foo();
base_type<CLASS_B> Class_B;
Class_B.bar();
base_type<CLASS_C> Class_C;
Class_C.foo();
Class_C.bar();
return 0;
}
Now if you need non-static functions that have access to private data-members, this can get a bit trickier, but it should still be doable. It would though most likely require the need for a separate traits class you can use to access the proper types without running into "incomplete types" compiler errors.
Thanks,
Jason
I think the problem is that when using simple inheritance between B and A, and between C and A, you end up with two objects of type A in D (each of which will have a pure virtual function, causing a compile error because D is thus abstract and you try to create an instance of it).
Using virtual inheritance solves the problem since it ensure there is only one copy of A in D.
How to stop the class to be inherited by other class.
C++11 solution
In C++11, you can seal a class by using final keyword in the definition as:
class A final //note final keyword is used after the class name
{
//...
};
class B : public A //error - because class A is marked final (sealed).
{ // so A cannot be derived from.
//...
};
To know the other uses of final, see my answer here:
What is the purpose of the "final" keyword in C++11 for functions?
C++03 solution
Bjarne Stroustrup's code : Can I stop people deriving from my class?
class Usable;
class Usable_lock {
friend class Usable;
private:
Usable_lock() {}
Usable_lock(const Usable_lock&) {}
};
class Usable : public virtual Usable_lock {
public:
Usable();
Usable(char*);
};
Usable a;
class DD : public Usable { };
DD dd; // error: DD::DD() cannot access
// Usable_lock::Usable_lock(): private member
Generic_lock
So we can make use of template to make the Usable_lock generic enough to seal any class:
template<class T>
class Generic_lock
{
friend T;
Generic_lock() {} //private
Generic_lock(const Generic_lock&) {} //private
};
class Usable : public virtual Generic_lock<Usable>
{
public:
Usable() {}
};
Usable a; //Okay
class DD : public Usable { };
DD dd; //Not okay!
There are two ways, the simple cheap, and the correct one. The two answers by #Naveen and #Nawaz deal with the correct one, that requires manual creation of a sealer class for each class that you actually want to seal.
The not fool-proof way, which is used in the adobe libraries is using a templated class for that. The problem is that you cannot declare the template argument as a friend, and that means that you will have to switch from private to the less safe protected:
template <typename T>
class sealer {
protected: sealer() {}
};
class sealed : virtual sealer<sealed> {};
And you can automate it with a macro (I don't remember the exact flavor of the macro in Adobe's code):
#define seal( x ) virtual sealer<x>
class sealed : seal(sealed)
{};
Now this will catch people that mistakenly try to inherit without knowing that they shouldn't:
class derived : sealed {};
int main() {
derived d; // sealer<T>::sealer() is protected within this context
}
But it will not inhibit people that really want to from deriving, as they can gain access to the constructor by deriving from the template themselves:
class derived : sealed, sealer<sealed> {};
int main() {
derived d;
};
I am not sure whether this will change in C++0x, I think I recall some discussions on whether a class template would be allowed to befriend one of it's arguments, but in a cursory search through the draft I cannot really tell. If that was allowed then this would be a fine generic solution:
template <typename T>
class sealer {
sealer() {}
friend class T; // Incorrect in C++03
};
C++11 adds the ability to prevent inheriting from classes or simply preventing overriding methods in derived classes. This is done with the special identifier final. For example:
class Base final { };
class Derived1 : Base { }; // ill-formed because the class Base has been marked final
or
class Base {
virtual void f() final;
};
class Derived : Base {
void f(); // ill-formed because the virtual function Base::f has been marked final
Note that final is not a language keyword. It is technically an identifier; it only gains special meaning when used in those specific contexts. In any other location, it can be a valid identifier.
Based on Bjarne Stroustrup's http://www.stroustrup.com/bs_faq2.html#no-derivation FAQ
with small modification without friend keyword usage:
// SEALED CLASS DEFINITIONS
class Usable_lock {
protected:
Usable_lock() {}
Usable_lock(const Usable_lock&) {}
};
#define sealed_class private virtual Usable_lock
// SEALED CLASS USAGE EXMAPLES
class UsableLast : sealed_class {
public:
UsableLast(){}
UsableLast(char*){}
};
class DD : public UsableLast {};
// TEST CODE
template <class T> T createInstance() {
return T();
}
int main()
{
createInstance<UsableLast>();
// createInstance<DD>();
return 0;
}
The following code shows how to define a sealed class in C++/CLI.
class A sealed
{
//here goes the class code
};
class B : public A
{
};
Now B : cannot inherit from A as it has been declared as 'sealed'. Also a detailed explanation about sealed keyword can be found here http://msdn.microsoft.com/en-us/library/0w2w91tf.aspx
Update: Added C++/CLI , also other answers have shown the latest C++11 way of achieving the same using final keyword.
You cannot. C++ is not Java or C#. And also there is no point, ever, IMHO.