I'm creating a list of classes for a program. However, the base class has multiple children, and some of the children have children as well. Would I need to alter my list in any way to accommodate the inherited classes? Thanks for any help!
Great, thanks for the help! This is an incredibly basic question, but when creating a grandchild class, would this be proper formatting?
Class C: Public B: Public A {
or just
Class C: Public B { ?
Take the following program:
#include <iostream>
#include <list>
struct A
{
virtual void hello()
{ std::cout << "Hello from A\n"; }
};
struct B : public A
{
virtual void hello()
{ std::cout << "Hello from B\n"; }
};
int main()
{
std::list<A> l1;
std::list<A*> l2;
A a;
B b;
l1.push_back(a);
l1.push_back(b);
l2.push_back(&a);
l2.push_back(&b);
l1.front().hello();
l1.back().hello();
l2.front()->hello();
l2.back()->hello();
}
We declare two lists, one using instances of class A, and one using pointers to A. You can put instances of B in the first list, since B is an A (due to inheritance). However, when you try to access the data and methods from items in the first list, you can not access data from B the items thinks they are of class A even if they are not.
For the second list it works though, because of the use of pointers and virtual overloading of the method.
I hope this helps a little with your question.
You are probably not creating a list of classes, but rather of instances of classes. There is a big difference. While a "class" is just the definition of data members and functions, an instance actually fills this definition with life.
That aside, you cannot put an instance of an inherited class into a list that has the parent class as storage type. This only works if you store pointers or references to the instances in the list and allocate the instances themselves elsewhere.
Problem with STL containers and inheritance is that STL containers store copies of objects, so all extended properties of child classes are lost in progress. Solution is to leave objects alone and do not copy them.
In STL containers you can store [smart] pointers to base class, so only pointer will be copied. Or you can go with intrusive lists like Boost::Intrusive or queue.h
it is only :
class C: public B {
and of course :
class B : public A {
C is a subclass of B which is a subclass of A.
if you want a list of a mix of instances of A, B and C, you have to declare it :
list<A*> myClassList;
Related
I have created two classes A and B where B inherits from class A. As you can see, I have a vector in class A that is currently under the protected section of the class. I am unsure if using protected is bad practice?
#include <vector>
class A
{
public :
A();
protected:
std::vector <std::string> a;
};
class B : A
{
public :
B();
void accessVector()
{
a.size();
}
private:
};
When A makes a data member a protected, it is offering the following guarantee to all classes that derive from it:
"You may do anything you like to a without telling me. This includes appending to it, modifying its contents, removing items, sorting it, moving from it, moving to it and otherwise making its state undefined and/or unknowable to me".
Remember that anyone may create a class that derives from A.
For this reason, to all intents and purposes, a protected member is a public member, since a derived class may simply say the following:
public:
using A::a;
Starting here and working forward, you'll find that there are only two sensible use-cases for protected:
When a base class defines a virtual member function that may need to be called from an overridden version of the same function in a derived class.
When the base class wants to expose 'data as interface' to a derived class, but not to the world.
This question already has answers here:
Can inner classes access private variables?
(5 answers)
Closed 6 years ago.
The title already says a lot,
but basically what i want to do is the following(Example):
I have a class called A, and another class inside a called B, like so:
class A
{
int a;
class B
{
void test()
{
a = 20;
}
};
};
As you can see my goal is for class B to have access to class A, as it is a nested class. Not this wont work, because B doesn't have access to A, but how can it get access?
Thank You
Despite that you declared class B inside of A, classes A and B are still completely independent. The only difference is that now to refer to B, one must do A::B.
For B to access A's stuff, you should use composition or inheritance. For composition, give B a reference to an object of A, like so:
class B {
public:
B(const A& aObj) : aRef(aObj) {
cout << aRef.a << endl;
}
private:
const A& aRef;
};
For inheritance, something like this:
class B: public A { // or private, depending on your desires
B() {
cout << a << endl;
}
}
The inner class is not related to the outer class in C++ as it is in Java. For an instance of A::B to access a member of an A object, it needs to have an instance of A somewhere, just as if B were not a nested class. Instances of A::B do not have any implicit instance of A; you can have many instances of A::B without any instances of A existing at all.
Pass an instance of A to test, and then use it to access the a member:
void test(A& a_instance)
{
a_instance.a = 20;
}
Classes are types, types don't have data. Instances have data, but an instance of A does not (in your example) contain an instance of B, and the instances of B don't have any knowledge of any instance of A.
Choices
have B be a child of A instead of contained by A
have B's constructor take a ref to the A instance which created it (preferred)
Now, if the variable a is private this still won't help. You will either need an accessor a or a friend relation.
C++ nested classes are not like java nested classes, they do not belong to an instance of A but are static. So a doesn't exist at that point
I have a C-header file with 100s of data structs. I want to make a superclass that each data struct inherits from. How to do that? Should I parse the header file? Reflection?
Because each C data struct is a public class, I could just make a superclass and... then what? I should not go in manually and explicitly make every struct inherit from the superclass?
If you have a bunch of structs:
The obvious answer is to make clever use of search and replace to make them inherit from the new base class. It wouldn't be able to access the members of the structs, but you could store pointers to them all in containers
struct base {
int dostuff() const {std::cout << "thing";}
};
struct thing1 : public base {
int size;
};
//otherstructs inheriting from base
int main() {
std::vector<std::unique_ptr<base>> objects;
objects.push_back(std::unique_ptr<base>(new thing1()));
objects[1].dostuff();
}
If making the base class thing is too hard, you might try adding functions via a wrapper class instead. You won't be able to store pointers to these in a container, but they can access members, as long as the structs have similar members.
struct thing1 {
int size;
};
//other unchanged structs
template<class mystruct>
struct wrapper : mystruct {
int getsize() {return mystruct.size;}
};
int main() {
wrapper<thing1> mything1;
std::cout << mything1.size << mything1.getsize();
}
Or, if you're just adding methods, make them separate functions:
struct thing1 {
int size;
};
//other unchanged structs
template<class T>
int getsize(const T& obj) {return obj.size;}
int main() {
thing1 mything1;
std::cout << mything1.size << getsize(mything1);
}
For your particular use case, I would leave the C code as is, and just create whatever solution you need in C++ leveraging the C code. You can for example, create a parallel hierarchy with a base that defines the interface that includes serialize() and deserialize() and each derived type storing one of the C structs and implementing the serialization of that particular type.
You can also tackle this completely externally, by providing templated serialize/deserialize functions that are defined for each one of the C structs... Inheritance is one of the most often abused features of C++.
The best solution will depend on how you intend on using the code, but I would avoid rewriting the C code (i.e. scripting an editor to rewrite the C header into a C++ solution) as that will effectively branch out of the C library and you will need to maintain two separate branches if you ever need to extend it C side.
I have never heard of structs using inheritance - it might be standard practice somewhere but all the examples of inheritance have been using a class - will it create a hardship to change the struct to a class? This could be confusing as I tend to think "C" when I see a struct.
Also are you sure that with inheritance, you still need 100's of structs or classes? If they really don't have duplicate data, that is OK, but if there are duplicated fields, it might be a good idea to have them inherit from each other to remove the duplicate fields.
There is no reflection in C/C++, and there is no one base class for other classes in C++, so this isn't an easy task. You can manually make every class you have inherit from the superclass as you suggested, or you can create a base class and then create a new structure for each data structs, which inherits it's concrete data struct and also the base class.
For example http://liveworkspace.org/code/7e06e0374ef41bc4aeeafd55ae143527 or http://liveworkspace.org/code/7e06e0374ef41bc4aeeafd55ae143527.
I think manually making each struct inherit from the base class in your C-header file is more efficient.
First off, I know I can not do it, and I think it's not a duplicate questions (this and this questions deal with the same problem, but they only want an explanation of why it does not work).
So, I have a similar concept of classes and inheritance and I would, somehow, elegantly, want to do something that's forbidden. Here's a very simple code snippet that reflects what I want to do:
#include <iostream>
class A{
protected:
int var;
std::vector <double> heavyVar;
public:
A() {var=1;}
virtual ~A() {}
virtual void func() {
std::cout << "Default behavior" << this->var << std::endl;
}
// somewhere along the way, heavyVar is filled with a lot of stuff
};
class B: public A{
protected:
A* myA;
public:
B(A &a) : A() {
this->myA = &a;
this->var = this->myA->var;
// copy some simple data, e.g. flags
// but don't copy a heavy vector variable
}
virtual ~B() {}
virtual void func() {
this->myA->func();
std::cout << "This class is a decorator interface only" << std::endl;
}
};
class C: public B{
private:
int lotsOfCalc(const std::vector <double> &hv){
// do some calculations with the vector contents
}
public:
C(A &a) : B(a) {
// the actual decorator
}
virtual ~C() {}
virtual void func() {
B::func(); // base functionality
int heavyCalc = lotsOfCalc(this->myA->heavyVar); // illegal
// here, I actually access a heavy object (not int), and thus
// would not like to copy it
std::cout << "Expanded functionality " << heavyCalc << std::endl;
}
};
int main(void){
A a;
B b(a);
C c(a);
a.func();
b.func();
c.func();
return 0;
}
The reason for doing this is that I'm actually trying to implement a Decorator Pattern (class B has the myA inner variable that I want to decorate), but I would also like to use some of the protected members of class A while doing the "decorated" calculations (in class B and all of it's subclasses). Hence, this example is not a proper example of a decorator (not even a simple one). In the example, I only focused on demonstrating the problematic functionality (what I want to use but I can't). Not even all the classes/interfaces needed to implement a Decorator pattern are used in this example (I don't have an abstract base class interface, inherited by concrete base class instances as well as an abstract decorator intreface, to be used as a superclass for concrete decorators). I only mention Decorators for the context (the reason I want a A* pointer).
In this particular case, I don't see much sense in making (my equivalent of) int var public (or even, writing a publicly accessible getter) for two reasons:
the more obvious one, I do not want the users to actually use the information directly (I have some functions that return the information relevant to and/or written in my protected variables, but not the variable value itself)
the protected variable in my case is much more heavy to copy than an int (it's a 2D std::vector of doubles), and copying it in to the instance of a derived class would be unnecessarily time- and memory-consuming
Right now, I have two different ways of making my code do what I want it to do, but I don't like neither of them, and I'm searching for a C++ concept that was actually intended for doing something of this sort (I can't be the first person to desire this behavior).
What I have so far and why I don't like it:
1. declaring all the (relevant) inherited classes friends to the base class:
class A{
....
friend class B;
friend class C;
};
I don't like this solution because it would force me to modify my base class every time I write a new subclass class, and this is exactly what I'm trying to avoid. (I want to use only the 'A' interface in the main modules of the system.)
2. casting the A* pointer into a pointer of the inherited class and working with that
void B::func(){
B *uglyHack = static_cast<B*>(myA);
std::cout << uglyHack->var + 1 << std::endl;
}
The variable name is pretty suggestive towards my feelings of using this approach, but this is the one I am using right now. Since I designed this classes, I know how to be careful and to use only the stuff that is actually implemented in class A while treating it as a class B. But, if somebody else continues the work on my project, he might not be so familiar with the code. Also, casting a variable pointer in to something that I am very well aware that it is not just feels pure evil to me.
I am trying to keep this projects' code as nice and cleanly designed as possible, so if anybody has any suggestions towards a solution that does not require the modification of a base class every now and then or usage of evil concepts, I would very much appreciate it.
I do believe that you might want to reconsider the design, but a solution to the specific question of how can I access the member? could be:
class A{
protected:
int var;
static int& varAccessor( A& a ) {
return a.var;
}
};
And then in the derived type call the protected accessor passing the member object by reference:
varAccessor( this->myA ) = 5;
Now, if you are thinking on the decorator pattern, I don't think this is the way to go.
The source of the confusion is that most people don't realize that a type has two separate interfaces, the public interface towards users and the virtual interface for implementation providers (i.e. derived types) as in many cases functions are both public and virtual (i.e. the language allows binding of the two semantically different interfaces). In the Decorator pattern you use the base interface to provide an implementation. Inheritance is there so that the derived type can provide the operation for the user by means of some actual work (decoration) and then forwarding the work to the actual object. The inheritance relationship is not there for you to access the implementation object in any way through protected elements, and that in itself is dangerous. If you are passed an object of a derived type that has stricter invariants regarding that protected member (i.e. for objects of type X, var must be an odd number), the approach you are taking would let a decorator (of sorts) break the invariants of that X type that should just be decorated.
I can't find any examples of the decorator pattern being used in this way. It looks like in C++ it's used to decorate and then delegate back to the decoratee's public abstract interface and not accessing non-public members from it.
In fact, I don't see in your example decoration happening. You've just changed the behavior in the child class which indicates to me you just want plain inheritance (consider that if you use your B to decorate another B the effects don't end up chaining like it would in a normal decoration).
I think I found a nice way to do what I want in the inheritance structure I have.
Firstly, in the base class (the one that is a base for all the other classes, as well as abstract base class interface in the Decorator Pattern), I add a friend class declaration only for the first subclass (the one that would be acting as abstract decorator interface):
class A{
....
friend class B;
};
Then, I add protected access functions in the subclass for all the interesting variables in the base class:
class B : public A{
...
protected:
A *myA;
int getAVar() {return myA->var;}
std::vector <double> &getAHeavyVar {return myA->heavyVar;}
};
And finally, I can access just the things I need from all the classes that inherit class B (the ones that would be concrete decorators) in a controlled manner (as opposed to static_cast<>) through the access function without the need to make all the subclasses of B friends of class A:
class C : public B{
....
public:
virtual void func() {
B::func(); // base functionality
int heavyCalc = lotsOfCalc(this->getAHeavyVar); // legal now!
// here, I actually access a heavy object (not int), and thus
// would not like to copy it
std::cout << "Expanded functionality " << heavyCalc << std::endl;
std::cout << "And also the int: " << this->getAVar << std::endl;
// this time, completely legal
}
};
I was also trying to give only certain functions in the class B a friend access (declaring them as friend functions) but that did not work since I would need to declare the functions inside of class B before the friend declaration in class A. Since in this case class B inherits class A, that would give me circular dependency (forward declaration of class B is not enough for using only friend functions, but it works fine for a friend class declaration).
So i have this type of inheritance:
Class A { virtual intfB(){} ; virtual intfC(){}; };
Class B : public A { int fB(){}; };
Class C : public A { int fC(){}; };
Then i have a class E that uses a list to store B and C objects.
Class E
{
public:
insert(A* obj){ l.push_front(obj);}
print(){ /* uses iterator i to cout the fB() and fC() of the objects in l */ };
private:
list <A*> l;
}
I set different functions of the B and C objects as virtual in A and then use an iterator i to access the l objects from within the print() function. My problem is that i cannot find a proper way to call B::fB() and C::fC() because the iterator can point to either a C or B object so i have to do something like this for each object that i don' t think is that practical:
cout << (*i) -> fB();
cout << (*i) -> fC();
So basicaly i call both fC and fB for every object regardless of type and the virtual function of the base class is called when it is not the correct object called.
This cannot be right tho, is it? How else can i achieve that?
On a side note should i use composition for classes E, C and B?
You're correct: Don't do it that way. If you want to print an item, call the function print in A, and override it in both child classes. Then you call print on each item as you iterate and each child does the right thing.
If intfB() and intfC() are technically the same function but with different implementations for B and C, then you should just declare one virtual function in A (perhaps called intf), and provide the necessary implementations for it in both B and C.
The idea of an abstract class is to define the base functionality that more detailed implementations of that class will share. So with the above described scheme, every object pointed to by the elements of your list will be guaranteed to have a intf() implementation.
I'm not sure that your example will compile (I have not tested that though) because neither B nor C provide implementations for the virtual functions declared in A.