I have an interface in C++ that looks something like this:
// A.h
#pragma once
class A
{
public:
//Some declarations.
private:
//Some declarations.
protected:
//Some declarations.
};
The specific form is not important. Since this is an interface, there will be a class B that inherits from A. In the header file for class B I have:
// B.h
#pragma once
class B : A
{
public:
//Some declarations.
private:
//Some declarations.
protected:
//Some declarations.
};
My concern is that I tend to use class B : A instead of class B : public A, just my bad memory.
So far I have had no issues with this, since it's a small enough project. But will forgetting the public keyword affect my project in any sense?
Or more succinctly, I know how access modifiers work but, what does class B : A default to?
The ONLY difference between struct and class is that in a struct, everything is public until declared otherwise, and in a class, everything is private until declared otherwise. That includes inheritance. So class B : A will default to private inheritance, and struct B : A will default to public inheritance.
What does class B : A default to?
class B : private A { /*...*/ }
But will forgetting the public keyword affect my project in any sense?
Yes. Don't forget it.
Consider the following:
// A.h
class A {
public:
void f(){}
};
// B.h
class B : A {};
int main() {
B b;
b.f(); // f is inaccessible because of private inheritance
}
Related
Suppose i have three classes A, B and C. class B inherits from class A and the inheritance is private whereas class C inherits from B and the inheritance is public. Now class A has a protected function which class C wants to access. So, what must be done in class B to make that protected function available to class C.
Here is the link to the code : http://pastebin.com/9E2sLZzj
The "using" keyword makes a member of an inherited class visible, and resolvable, in the scope of its subclass. So, to make the privately-inherited member available to B's subclasses:
class A {
protected:
void foo() {}
};
class B : private A {
protected:
using A::foo;
};
class C : public B {
void bar()
{
foo();
}
};
Okay i got the solution
This code fragment worked after inserting it into Class B.
int get(){
return A::get();
}
Not sure what it does though
I am little bit confused on referencing a sub class inside a super class in C++.
For example, given Java :
public class Entity {
protected ComplexEntity _ce;
public Entity() {
}
public ComplexEntity getCentity() {
return _ce;
}
}
Where ComplexEntity extends the entity.It works.In the sub class I call getCentity() no errors.
Now ,in C++ when I write something like that:
#pragma once
#include "maininclude.h"
#include "ExtendedEntity.h"
using namespace std;
class EntityBase
{
public:
EntityBase(void);
EntityBase(const string &name);
~EntityBase(void);
protected:
ExtendedEntity* _extc;
string _name;
};
I am getting compiler error:
error C2504: 'Entity' : base class undefined
In the classes which inherit from this Entity.Why does that happen?
Is it completely unacceptable in C++?
May be Entity must be abstract ?
I would like to get suggestions on possible workarounds.
You may consider using CRTP, cut/paste from Wikipedia:
// The Curiously Recurring Template Pattern (CRTP)
template<class Derived>
class Base
{
Derived* getDerived() { return static_cast<Derived*>(this); }
};
class Derived : public Base<Derived>
{
// ...
};
Your code is like the following:
struct D : B {}; // error: B doesn't mean anything at this point
struct B {
D *d;
};
Your header ExtendedEntity.h is trying to use the definition of Entity before Entity is defined.
You need to change your code to this:
struct D;
struct B {
D *d;
};
struct D : B {};
A class in C++ needs to know the size of all its members and of all its superclasses. Class Entity does not know the size of it's subclass ComplexEntity, unless class ComplexEntity is defined before class Entity. But then, class ComplexEntity does not know the size of its superclass Entity.
This problem exists in C++, because class members are accessed using simple offset calculation. You can work around this, by forward declaring the derived class and using pointers as members:
class Extended; // declare the derived class
class Base { // define the base class
Extended* e; // you cannot use Extended e here,
// because the class is not defined yet.
};
class Extended : public Base {}; // define the derived class
By 'promote' I mean make access more restrictive and by 'demote' I mean make less restrictive.
For example, when class B is derived from class A using : protected or : private then the public members of A get promoted, to protected and private, respectively.
Could some class C ever come in and derive itself from class B, while at the same time demoting the inherited members of class A back to their original access specifications?
If you're using protected derivation, then class C could indeed give access to the protected members, by creating an appropriate wrapper:
class A {
public:
void F();
};
class B : protected A { };
class C : public B {
public:
using B::F;
};
This also can be made to work with data members:
class A {
public:
int n;
};
class B : protected A { };
class C : public B {
public:
using B::n;
C() : n(this->B::n) { }
};
With private inheritance this is not directly possible, because C cannot itself access members in A.. However, if B is derived from A using private virtual inheritance, it becomes possible again:
class A {
public:
void F();
};
class B : private virtual A { };
class C : public B, public virtual A { };
int main() {
C x;
x.F();
return 0;
}
This works because with virtual inheritance, C can derive directly from the same instance of A as B, but with a different access specifier.
A using declaration can give access to public or protected members of protected base classes:
struct A {int x;};
struct B : protected A {};
struct C : B
{
using A::x; // publicly accessible
}
Obviously, private members and base classes aren't available to C, so you can't reduce the restrictions on them.
Of course not, what would be the point of having private or protected inheritance if I can just create another derived that class that blows away the intermediate class' access restrictions and makes everything public?
No.
Because, when class C derives class B; it doesn't know about the original access specifiers of class A. It just respects the access specifiers in class B.
I have this setup:
class A
{
public:
virtual void Function();
}
class B : private A
{
}
class C : public B
{
public:
// I want to expose A::Function() here
}
I tried to do this by adding:
class C : public B
{
public:
virtual void Function();
}
and
C::Function()
{
A::Function();
}
but I get and "inaccessible base" error.
Is it possible to do something like this?
In B you can change the accessibility of A::Function to protected:
class B : private A
{
protected:
using A::Function;
};
In C::Function (and elsewhere in C) you will then have to refer to the function as B::Function, not A::Function. You could also public: using B::Function; in C instead of implementing a C::Function that just calls B::Function.
You can't do this. The fact that B inherits from A is an implementation detail and you are not allowed to access it from C- just like you can't access B's private functions or member variables.
This would be completely legal if B inherited protected or public from A.
If you can change it to class B : protected A it should work.
Not really. The scenario you're describing would indicate that your class hierarchy needs to be reworked.
If I have for example two classes A and B, such that class B inherits A as follows:
class B: public A
In this case, I'm doing public inheritance.
If I write the previous code as follows:
class B: A
What type of inheritance will I be doing here (i.e; public)? In other words, what is the default access specifier?
Just a side question here. Do I call the previous line of codes statements? Especially that I remember I read in the C++ Without Fear: A Beginner's Guide That Makes You Feel Smart book that statements are that that end with ;. What do you think about that?
Thanks.
Just a small addition to all the existing answers: the default type of the inheritance depends on the inheriting (derived) type (B in the example), not on the one that is being inherited (base) (A in the example).
For example:
class A {};
struct B: /* public */ A {};
struct A {};
class B: /* private */ A {};
It's private for class and public for struct.
Side answer: No, these are definitions of the class according to the standard. Class definition end with a semicolon. On the other hand not all statements end with a semicolon (e.g. an if statement does not).
When you inherit a class from another class (inherit class Base from class Derived in this case), then the default access specifier is private.
#include <stdio.h>
class Base {
public:
int x;
};
class Derived : Base { }; // is equilalent to class Derived : private Base {}
int main()
{
Derived d;
d.x = 20; // compiler error becuase inheritance is private
getchar();
return 0;
}
When you inherit a class from a structure (inherit class Base from struct Derived in this case), then the default access specifier is public.
#include < stdio.h >
class Base {
public:
int x;
};
struct Derived: Base {}; // is equilalent to struct Derived : public Base {}
int main() {
Derived d;
d.x = 20; // works fine becuase inheritance is public
getchar();
return 0;
}
If you use class to define your class, the default access specifier will be private. (I think it's wrong, too.) If you use struct, however, it will be public.
And class definitions are declarations, I think. A statement is what translates into actual code (unless optimized away, anyway).
However, a mildly exotic feature of C and C++ is that expressions are statements. That's why 3+4; is a syntactically legal statement in C++ (although many compilers will warn about it having no effect). While it is obviously nonsense in this case, in general expressions are evaluated for their side effects. (An obvious example is discarding a function's return value. You call the function not to obtain a result, but for its side effects.)
The "type" of inheritance depends on how the class is defined. There are default access specifiers applied to inheritance. From the C++ standard:
[class.access.base]/2
In the absence of an access-specifier for a base class, public is
assumed when the derived class is defined with the class-key struct
and private is assumed when the class is defined with the class-key
class. [ Example:
class B { /* ... */ };
class D1 : private B { /* ... */ };
class D2 : public B { /* ... */ };
class D3 : B { /* ... */ }; // B private by default
struct D4 : public B { /* ... */ };
struct D5 : private B { /* ... */ };
struct D6 : B { /* ... */ }; // B public by default
class D7 : protected B { /* ... */ };
struct D8 : protected B { /* ... */ };
Here B is a public base of D2, D4, and D6, a private base of D1, D3,
and D5, and a protected base of D7 and D8. — end example ]
If you do not choose an inheritance, C++ defaults to private inheritance in the same way class members default to private access for classes.
The default type of the inheritance is private in C++.
class B:A
{};
is equivalent to
class B: private A
{};
the default access specifier is an important differentiator between classes and structs. It is public by default for structs and private by default for classes.
AS other casting problem you have
class A { virtual void test() = 0; };
class B : virtual public A { virtual void testb() {} };
class C : virtual public A { virtual void testc() {} };
class D : public B, public C {
virtual void test() override {}
}
void main() {
D d;
void* v = &d;
A* a = &d;
((D*)A)->test(); //OK
((D*)v)->test(); //undefined behavior (that call testb() in vtable logic at 1st inheritance position)
dynamic_cast<D*>(v)->test(); //compile error cast from void* not permitted
//resolution
void* x = a;
((D*)x)->test(); //OK but as you can see, you must to store a* in x*
}