I want to specify an interface which requires an abstract class to have a certain type as a member variable.
I'll try to replicate the situation here:
class Blob {
int data[32];
};
class Worker {
string name;
abstract void workOn(Blob&) = 0;
}
class Abstract {
vector<shared_ptr<W>> workerList;
Blob allTheStuff;
abstract void somethingElse() = 0;
void doAllTheWork() {
for (w : workerList) {
w->workOn(allTheStuff);
}
}
};
class B_Blob : public Blob {
int moreData[4096];
};
class BulbasaurTrainingCamp : public Abstract {
B_Blob allTheStuff;
void somethingElse() {} // implemented
// this class will accept Bulbasaurs into workerList
};
class Bulbasaur : Worker {
Bulbasaur(): name("Fushigidane") {}
void workOn(Blob& b) {
// bulbasaurs cover *all* their workspace with crap
for (int i=0; i<sizeof(b.data[0])/sizeof(b.data); ++i) {
b.data[i] = *((int*)&("crap"));
}
for (i=0; i<sizeof(b.moreData[0])/sizeof(b.moreData); ++i) {
b.moreData[i] = *((int*)&("crap"));
}
}
Here, the abstract bas class has a Blob, but the instance of BulbasaurTrainingCamp has a derived B_Blob. It appears that since I gave it the same name, the compiler accepts it.
Is there a name for this? What I want to know is what the behavior is when I do this. Have I overridden the Blob with the B_Blob?
I am basically not sure about whether there is an inaccessible base Blob instance hanging around inside of BulbasaurTrainingCamp. My expectation is that each Bulbasaur will write 16512 (not 16384) bytes of crap across the two member variables of B_Blob. I am hoping that C++ will actually do what appears to be the sensible thing. It's a case of, "it compiles so I think I should be happy, but I'm still not totally sure it's doing what I think it should be doing".
#include<iostream>
#include<vector>
using namespace std;
int main()
{
class base
{
public:
int sameName;
base(int x):sameName(x){}
};
class derived : public base
{
public:
int diffName;
int sameName;
derived(int x,int i,int j):base(x),diffName(i),sameName(j){}
};
derived example(1,2,3);
cout<<example.sameName<<endl;
cout<<example.diffName<<endl;
cout<<example.base::sameName<<endl;
}
The result is 3 2 1.
I hope the example could be helpful.
A base class, even an abstract one, will be included in its entirety within any derived classes. The new allTheStuff name hides the old one, but does not suppress its inclusion; the base class version can still be accessed using Abstract::allTheStuff. Worse, the function doAllTheWork will end up accessing the base class allTheStuff because it can't possibly know there's an identically-named member variable in a subclass.
If you want this kind of behaviour, you have a few decent options:
Don't put any meaningful code or data in the base class; leave it as a pure interface. This may result in code duplication (but you may be able to factor it out into new base classes or shared helper functions).
Use a dynamically sizable container type as the Blob, so you can dynamically ask for more or less space in the constructor.
Make Blob a separate inheritance hierarchy (e.g. B_Blob and S_Blob inherit from an abstract Blob with differing amounts of space allocated), with a virtual function in Abstract that returns the Blob to use.
You seem to be somehow assuming that this code compiles using C++. It certainly doesn't. Even after patching about various of the C++/CLI specifics, it remains that a Blob does not have a data member called moreData and the only way to get at it (using C++) is to use a suitable cast.
The BulbasaurTrainingCamp objects will have two members called allTheStuff, one of type Blob and one of type B_Blob. Which one you get depends on which type you are looking at (since all members are private, you won't get any, but let's ignore that detail) and/or which qualification you use:
BulbasaurTrainignCamp btc;
B_Blob& b_blob = bts.allTheStuff;
Blob& blob1 = bts.Abstract::allTheStuff;
Abstract& abstract;
Blob& blob2 = abstract.allTheStuff;
That is, when using something which looks like a BulbasaurTrainingCamp you can access both the Blob and the B_Blob objects but you need to use qualification to access Abstracts allTheStuff member. When using an Abstract you can only access Abstracts Blob object.
Related
I have this large class that I want to separate into different classes. The reason why it was large because the class had many private variables and functions that are needed to run the program. I was tired of scrolling down the 1000+ lines of code trying to add or edit code. I am wondering if it is possible for the classes to interact with one base class that includes all the private/protected variables it needed to operate, or simply have them as global variables.
I am aware of inheritance as I tried having the separate classes be derived from the base class, by doing something similar to this:
#include <iostream>
class Base {
public:
void sayPrivateVar() {
std::cout << privateVar;
}
protected:
std::string privateVar = "I am a protected variable!";
};
class Derived : public Base {
public:
void manip() {
base->privateVar = "That was updated from a derived class";
}
private:
Base* base;
};
int main() {
Base base;
Derived derived;
derived.manip();
base.sayPrivateVar();
return 0;
}
EDIT: Without creating another object inside a class.
it depends on your class and what you have in it. It is often better not have inheritance because derived classes may then get member variables that they don't need. There are a few other ways you can do. One way would be to group you private variables in different classes and then have member variables in the first class.
E.g.
class X {
int x;
int y;
int angle;
...
};
becomes
class XYVector;
class X {
XYVector v;
};
class XYVector
{
int x;
int y;
int angle;
};
You can continue in this direction and instead of making them concrete class like XYVector above have them as interfaces : to have it more elaborate and flexible check out https://en.wikipedia.org/wiki/Composition_over_inheritance
At any rate: avoid having globally declared variables.
This is a good question and the answer is absolutely. Inheritance is actually a very good solution in this particular context since that is how object code shares it's scope with other classes. One important thing to note here is that how you call your derived class is important because the inherited scope is set along with the derived class (i.e. declaring it public base would inherit the public and protected methods as opposed to declaring it private which would give the derived class even more access!)
There are a lot of questions about this topic, but however, I didn't find the solution for my following question:
I have the following classes:
1) The pure virtual class
class Employee {
private:
vector<Employee> vec_employee;
public:
Employee() {};
virtual ~Employee() {};
virtual void set_vec_subordinate(vector<Employee> vec_employee) = 0;
};
2) A derived class
class Worker : Employee{ private: public: };
3) Another derived class which should override the pure virtual method from Employee
class Manager : Employee {
private:
public:
inline void set_vec_subordinate(vector<Worker> vec_employee) override { this->set_vec_subordinate(vec_employee); };
};
What I try to achieve is to override the pure virtual method but use a "different" parameter. So still new to C++ but I think there should be a way to do so, especially because the other parameter is from type Worker which is a derived class from Employee.
There is no way to do exactly what you plan to do (and there is good reason for that).
Your code is also inherently broken, as you use the type vector<Employee>, which requires objects of type Employee - which cannot exist, as Employee is an abstract class. You may wish to use a vector of a reference type, e.g., vector<shared_ptr<Employee>> instead. (The rest of this answer glosses over this fact to make it more readable.)
Note also that void Manager::set_vec_subordinate(vector<Worker> vec_employee) override { this->set_vec_subordinate(vec_employee); }; would cause an infinite loop (probably resulting in a stack overflow) when called, as it will just keep calling itself.
The class Employee has a contract with its users, that says the following code must be valid (assuming given get_boss and get_workers functions):
Employee& boss = get_boss();
vector<Employee> subordinate_vec = get_workers();
boss.set_vec_subordinate(subordinate_vec);
Now, this might not make any semantic sense for your application, but the syntax of the programming language means that this must be possible. Some programming languages (not C++!) allow covariant calls similar to this:
Employee& boss = get_boss();
vector<Worker> subordinate_vec = get_workers();
boss.set_vec_subordinate(subordinate_vec); // Invalid C++: `vector<Worker` cannot be converted to `vector<Employee>` implicitly
While it is indeed possible to create a container in C++ that behaves in a way so that this use is possible, it is easier to deal with it is by making the set_vec_subordinate function a template that requires an arbitrary container of objects that are implicitly convertible or derived from Employee - and then just converting the objects during the copy operation (since the vector is not movable in that case anyway).
The second idea is that it should be possible to change the signature of a function when overriding it. This is kind of possible in C++ by implementing the base case (which needs to be binary compatible with - a.k.a. equal to - the signature of the Employee version, as it will be called for that case as well) and then adding additional overloads. For example, you could do something along the lines of:
class Manager : Employee {
private:
public:
inline void set_vec_subordinate(vector<Employee> vec_employee) override { this->vec_employee = std::move(vec_employee); };
inline void set_vec_subordinate(vector<Worker> const& vec_worker) {
vec_employee = std::vector<Employee>(vec_worker.begin(), vec_worker.end()); // copy convert all elements
};
};
I am a newbiee in C++.
I have two pure abstract classes (like interfaces), and I derive a Class from these two pure abstracts classes.
In a case, I need to upcast the derived class pointer to one of the base abstract classes.
First of all, is there any limitation on that.
class IBase1
{
virtual ~IBase() = default;
}
class IBase2
{
virtual ~IBase2() = default;
}
class Derived : public IBase, public IBase2
{
}
Derived d;
IBase1* basePtr = dynamic_cast<IBase1*>(&d);
Herein, if I use any other cast, I am not pretty sure but I get invalid pointer from the cast, so I need to use dynamic_cast for upcasting from multiple inheritance, is that right?
When I do that, I get an error "source type is not polymorphic"
My base classes are pure abstract classes so they have at least one virtual methid so it should be ok, right but why I get this error? Is it about the multiple inheritance?
Edit: There are one more layer here.
My Derived Class needs to contain two different type of instances but my instances are really huge variable so as a C developer :), I was planning to use an Union for less memory usage.
The union has only instances of two classes which derived from pure abstract classes. So, I was assuming that the union instance address should also points the offsets of my class instances, but C++ cannot probably know the write member methods address.
class IFile
{
public:
virtual ~IFile() = default;
};
class IDirectory
{
public:
virtual ~IDirectory() = default;
};
class FileSystem1 : public IFile, public IDirectory
{
public:
FileSystem1() { }
virtual ~FileSystem1() final override = default;
private:
Native1APIInstance file;
};
class FileSystem2 : public IFile, public IDirectory
{
public:
FileSystem2() { }
virtual ~FileSystem2() final override = default;
private:
Native2APIInstance file;
};
union FileSystemInstance
{
FileSystem1 fs1;
FileSystem2 fs2;
FileSystemInstance(string path)
{
if (path[0] == '1') // initialise fs1
else if (path[0] == '2') // initialise fs2
}
};
FileSystem fs("<PATH to File System>");
IFile* file = reinterpret_cast<IFile*>(&fs);
Herein, I dont want to interest which instance is initialised. I want to work with only the base class interface. I am wondering is that somehow possible with an Union?
Thanks.
class FileSystem1 : public IFile, public IDirectory
Let's sit back and think about just that much for a moment. That asserts that a FileSystem1 is (or more formally, under any possible circumstances, can be used in place of) either an IFile or an IDirectory.
At least as most people use these terms, that's not how things are at all. As most people use the terms, a File system contains some things, each of which can be either a file or a directory:
class FS_node {
virtual std::string name() const { return name_; }
// ...
virtual ~FS_node = default;
};
class File : public FS_node {
// ...
};
class Directory : public FS_node {
// ...
};
class FileSystem {
std::vector<FS_node *> nodes;
public:
// ...
};
Now, from the sound of things, you have to deal with two entirely separate file systems. There are a number of ways of doing that. One possibility would be to have a base FileSystem class that defines an interface to a file system, then have two derivative classes that implement that interface in terms of two separate APIs at the OS level.
Another possibility would be to implement similar functionality, but instead of using inheritance, you'd specify the API interface class as a template parameter when you instantiate a FileSystem object:
template <class Api>
class FileSystem {
Api api;
public:
FileSystem(Api const &api) : api(api) {}
// FS functions for finding files and such go here,
// each implemented via the `Api` passed as a parameter
};
As to the difference between using templates and inheritance: it's pretty much the same as usual: templates are static, so if (for example) you want code that you can specify at compile time whether to compile for Windows or Linux, templates should work nicely. On the other hand, if you're dealing with something like a single collection of file systems, and that collection might contain a mixture of objects, each representing a different file system, and you want to be able to deal with all of them transparently at run time, then you'll probably need to use an inheritance hierarchy.
But at least to me, it seems fairly likely that your original design with FileSystem derived from both File and Directory classes is almost certainly a pretty serious mistake. We'd probably need to know a bit more about what you're doing to be sure of what approach is really optimal, but that's probably not it.
Ignoring all of that about the design for a moment, and looking at the question of how to convert from pointer to derived to point to base, we really have only two cases that matter a whole lot. If you used public inheritance (as shown in the question), the conversion doesn't require a cast at all:
FileSystem1 foo1;
IFile *fileBase = &foo1; // No problem.
IDirectory *dirBase = &foo1; // Likewise
If you used private derivation, then you've just found an exceptionally rare situation: one where you actually need to use a C-style cast to do the conversion properly:
class Base1 {};
class Base2 {};
// Note: private derivation:
class Derived : Base1, Base2 {};
Derived d;
Base1 *b1 = (Base1 *)&d;
Base2 *b2 = (Base2 *)&d;
For this specific case (converting a derived class to an inaccessible base class) none of the "new" C++ casts can do the job--you must us a C-style cast.
It seems the problem is about Union data structure.
For example, if I use union while the following works;
FileSystem fs;
fs.fs1.Func();
the below does not work
FileSystem fs;
FileSystem1* fs1 = &fs.fs1; (No casting, the same type)
fs1->Func();
I got an exception for the second case, it somehow cannot find the virtual function table (Access violation for vtable; 0xCCCCCCCC). Does not make sense to me.
If I change Union to Class type, the same code works. It must be about the Union itself. I need to study it well, or leave the idea. Thank you all.
I am confused about the concepts of inheritance and polymorphism. I mean, what is the difference between code re-usability and function overriding? Is it impossible to reuse parent class function using inheritance concept or else is it impossible to override parent class variables using Polymorphism. There seems little difference for me.
class A
{
public:
int a;
virtual void get()
{
cout<<"welcome";
}
};
class B:public A
{
a =a+1; //why it is called code reuse
void get() //why it is called overriding
{
cout<<"hi";
}
};
My doubt is about the difference between the code reuse and function overriding.
Lets start with your example.
class A
{
public:
int a;
virtual void get()
{
cout<<"welcome";
}
};
class B:public A
{
a =a+1; //why it is called code reuse
void get() //why it is called overriding
{
cout<<"hi";
}
};
Inheritance: Here you are deriving class B from class A, this means that you can access all of its public variables and method.
a = a + 1
Here you are using variable a of class A, you are reusing the variable a in class B thereby achieving code reusability.
Polymorphism deals with how a program invokes a method depending on the things it has to perform: in your example you are overriding the method get() of class A with method get() of class B. So when you create an instance of Class B and call method get you'll get 'hi' in the console not 'welcome'
Function inheritance allows for abstraction of behaviour from a "more concrete" derived class(es) to a "more abstract" base class. (This is analogous to factoring in basic math and algebra.) In this context, more abstract simply means that less details are specified. It is expected that derived classes will extend (or add to) what is specified in the base class. For example:
class CommonBase
{
public:
int getCommonProperty(void) const { return m_commonProperty; }
void setCommonProperty(int value) { m_commonProperty = value; }
private:
int m_commonProperty;
};
class Subtype1 : public CommonBase
{
// Add more specific stuff in addition to inherited stuff here...
public:
char getProperty(void) const { return m_specificProperty1; }
private:
char m_specificProperty1;
};
class Subtype2 : public CommonBase
{
// Add more specific stuff in addition to inherited stuff here...
public:
float getProperty(void) const { return m_specificProperty2; }
private:
float m_specificProperty2;
};
Note that in the above example, getCommonProperty() and setCommonProperty(int) are inherited from the CommonBase class, and can be used in instances of objects of type Subtype1 and Subtype2. So we have inheritance here, but we don't really have polymorphism yet (as will be explained below).
You may or may not want to instantiate objects of the base class, but you can still use it to collect/specify behaviour (methods) and properties (fields) that all derived classes will inherit. So with respect to code reuse, if you have more than one type of derived class that shares some common behaviour, you can specify that behaviour only once in the base class and then "reuse" that in all derived classes without having to copy it. For example, in the above code, the specifications of getCommmonProperty() and setCommonProperty(int) can be said to be reused by each Subtype# class because the methods do not need to be rewritten for each.
Polymorphism is related, but it implies more. It basically means that you can treat objects that happen to be from different classes the same way because they all happen to be derived from (extend) a common base class. For this to be really useful, the language should support virtual inheritance. That means that the function signatures can be the same across multiple derived classes (i.e., the signature is part of the common, abstract base class), but will do different things depending on specific type of object.
So modifying the above example to add to CommonBase (but keeping Subtype1 and Subtype2 the same as before):
class CommonBase
{
public:
int getCommonProperty(void) const { return m_commonProperty; }
void setCommonProperty(int value) { m_commonProperty = value; }
virtual void doSomething(void) = 0;
virtual ~CommonBase() { }
private:
int m_commonProperty;
};
Note that doSomething() is declared here as a pure virtual function in CommonBase (which means that you can never instantiate a CommonBase object directly -- it didn't have to be this way, I just did that to keep things simple). But now, if you have a pointer to a CommonBase object, which can be either a Subtype1 or a Subtype2, you can call doSomething() on it. This will do something different depending on the type of the object. This is polymorphism.
void foo(void)
{
CommonBase * pCB = new Subtype1;
pCB->doSomething();
pCB = new Subtype2;
pCB->doSomething(); // Does something different...
}
In terms of the code sample you provided in the question, the reason get() is called "overriding" is because the behaviour specified in the B::get() version of the method takes precedence over ("overrides") the behaviour specified in the A::get() version of the method if you call get() on an instance of a B object (even if you do it via an A*, because the method was declared virtual in class A).
Finally, your other comment/question about "code reuse" there doesn't quite work as you specified it (since it's not in a method), but I hope it will be clear if you refer to what I wrote above. When you are inheriting behaviour from a common base class and you only have to write the code for that behaviour once (in the base class) and then all derived classes can use it, then that can be considered a type of "code reuse".
You can have parametric polymorphism without inheritance. In C++, this is implemented using templates. Wiki article:
http://en.wikipedia.org/wiki/Polymorphism_%28computer_science%29#Parametric_polymorphism
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).