As we all know, C++ allows multiple inheritance.
Context
I'm implementing a processing network where some processing nodes are link between each other to exchange different data with a sort of modified Observer pattern.
A node which can send a certain type of data is a "DataSender" and then extends this abstract class.
A node which can receive a certain type of data is a "DataReceiver" and then extends this abstract class.
Here is my piece of code :
DataReceiver.h
template <typename TReceivedData>
class DataReceiver {
public:
void receiveData(TReceivedData* receivedData)
{
m_receivedData = receivedData;
}
TReceivedData* getReceivedData()
{
return(m_receivedData);
}
private:
TReceivedData* m_receivedData;
DataSender.h
template <typename TSentData>
class DataSender {
public:
void sendData(TSentData* sentData)
{
set<DataReceiver<TSentData>*>::const_iterator it;
for(it = m_receiverList.begin(); it != m_receiverList.end(); ++it)
(*it)->receiveData(sentData);
}
void addDataReceiver(DataReceiver<TSentData>* dataReceiver)
{
m_receiverList.insert(dataReceiver);
}
void removeDataReceiver(DataReceiver<TSentData>* dataReceiver)
{
m_receiverList.erase(dataReceiver);
}
private:
set<DataReceiver<TSentData>*> m_receiverList;
};
Then a new node is simply implemented by extending one or both of these abstract classes.
Question
I want a node which sends a data of type "Image" and "Text" : then I have a node :
with:
class Node : public DataSender<Image>, DataSender<Text>
Well, i guess you've already seen my problem, the compilation won't allow this as there's an ambiguity if I launch :
Node* node;
node->sendData(<my argument>);
because it has no way to distinguish which sendData() from the parents classes (from inheritance) should be used (that's a common problem of multiple inheritance).
1) Is there a way to use sendData() with something to solve the ambiguity (i am not sure there is one ?
2) Is there another way to solve my problem of communication ? (I absolutely want to have the opportunity that the final user which wants to create a node which sends/receives data can do it easily simply by extending something like an interface, and datas should be on different "channels": a node for instance could be able to process text and image, but will only send image...
Thanks for your help,
Julien,
It's not pretty, but you can tell which base class' function you intend to call
node->DataSender<Text>::sendData(<my argument>);
I don't think you have an ambiguity problem, because the two sendData member functions take different arguments. The problem is more likely caused by the fact that when determining which function to call C++ checks base classes in a specific order, but stops in the first one that has a member function of the correct name. Then, if it has found one that can take the argument you supplied it calls it, otherwise it issues the error you probably saw.
What you can do to overcome this problem is to add the following lines to your Node class definition:
using DataSender<Image>::sendData;
using DataSender<Text>::sendData;
Related
I've been working on a project for the past few days that involves three linked lists.
Here is an example of the header with the nodes and the lists themselves:
class nodeA
{
int data1;
double data2;
nodeA* next;
}
class listA
{
nodeA* headA;
...
}
class nodeB
{
int data3;
double data4;
nodeB* nextB;
}
class listB
{
nodeB* headB;
...
}
class nodeC
{
int data5;
double data6;
nodeC* nextC;
}
class listC
{
nodeC* headC;
...
}
What i'd like to know is how can i save the lists that i declare in my main so that if i close the program and then open it again i can recover the lists data
So lista_vendas::novaVenda needs to call lista_produto::escolheProduto.
To call lista_produto::escolheProduto you need a lista_produto object. Where are you going to get that lista_produto object from?
There's really only three ways this can be done. I don't know which way is the correct way for you, but I'll list them and you can decide.
1) Have a lista_produto global variable, a global list of products. Then lista_vendas::novaVenda can use the global lista_produto to call lista_produto::escolheProduto. This is the simple solution, but global variables are rightly considered bad style. It also means that you program can only have one list of products, is that a problem? Think carefully before trying this solution.
2) Have a lista_produto as a member variable of lista_vendas or no_vendas. I guessing here but perhaps something like this
class no_vendas
{
public:
unsigned int codigoVenda, dia, mes, ano, numeroItens;
double precoTotal;
lista_produto productList; // list of products
no_vendas* proxi; //referencia para o proximo no
};
Now each vendor has a list of products, which makes sense. So lista_vendas::novaVenda now has access to a lista_produto in each no_vendas and it can use that to call lista_produto::escolheProduto. If this makes sense then this is problably the best solution.
3) Pass a lista_produto as a parameter to lista_vendas::novaVenda. Like this
void novaVenda(unsigned int codigoVenda, lista_produto* productList);
So whatever code calls lista_vendas::novaVenda must also supply the lista_produto that it needs.
As I said I don't know which of these possibilities is correct, because I don't know what you are trying to do (and I don't speak Spanish). But this is a problem in the relationships between your different objects. It's up to you to design your classes so that they can access the different objects that they need to work.
You mentioned inheritance in your title, but this doesn't feel like the right thing to do in this case.
This won't help you with your concrete problem at hand but I think you should use standard containers like std::vector<>. Implementing your own linked list is a nice finger exercise but seldom really necessary. That said, you should use std::vector<no_produto> instead of lista_produto:
#include <vector>
std::vector<no_produto> my_lista_produto;
// fill the vector:
my_lista_produto.push_back(my_no_produto_1);
my_lista_produto.push_back(my_no_produto_2);
// ...
// retrieve one item:
const no_produto &p = my_lista_produto[1];
// clear all items:
my_lista_produto.clear();
A complete list of all available methods can be found here.
Concerning your question: The question title mentions inheritance but there isn't any inheritance used in your example. In order to derive class B from class A you have to write
class A {
public:
void func();
};
class B : public A {
public:
void gunc();
};
This means essentially, B can be treated as an A. B contains the content of A and exposes the public interface of A by itself. Thus we can write:
void B::gunc() {
func();
}
even though B never defines the method func(), it inherited the method from A. I suspect, that you didn't inherit your classes properly from each other.
In addition to my initial thoughts about writing you own linked lists, please consider also composition instead of inheritance. You can find more information about the topic at Wikipedia or on Stack Overflow.
i'm creating particle system and i want to have possibility to choose what kind of object will be showing on the screen (like simply pixels, or circle shapes). I have one class in which all parameters are stored (ParticleSettings), but without those entities that stores points, or circle shapes, etc. I thought that i may create pure virtual class (ParticlesInterface) as a base class, and its derived classes like ParticlesVertex, or ParticlesCircles for storing those drawable objects. It is something like that:
class ParticlesInterface
{
protected:
std::vector<ParticleSettings> m_particleAttributes;
public:
ParticlesInterface(long int amount = 100, sf::Vector2f position = { 0.0,0.0 });
const std::vector<ParticleSettings>& getParticleAttributes() { return m_particleAttributes; }
...
}
and :
class ParticlesVertex : public ParticlesInterface
{
private:
std::vector<sf::Vertex> m_particleVertex;
public:
ParticlesVertex(long int amount = 100, sf::Vector2f position = { 0.0,0.0 });
std::vector<sf::Vertex>& getParticleVertex() { return m_particleVertex; }
...
}
So... I know that i do not have access to getParticleVertex() method by using polimorphism. And I really want to have that access. I want to ask if there is any better solution for that. I have really bad times with decide how to connect all that together. I mean i was thinking also about using template classes but i need it to be dynamic binding not static. I thought that this idea of polimorphism will be okay, but i'm really need to have access to that method in that option. Can you please help me how it should be done? I want to know what is the best approach here, and also if there is any good answer to that problem i have if i decide to make that this way that i show you above.
From the sounds of it, the ParticlesInterface abstract class doesn't just have a virtual getParticleVertex because that doesn't make sense in general, only for the specific type ParticlesVertex, or maybe a group of related types.
The recommended approach here is: Any time you need code that does different things depending on the actual concrete type, make those "different things" a virtual function in the interface.
So starting from:
void GraphicsDriver::drawUpdate(ParticlesInterface &particles) {
if (auto* vparticles = dynamic_cast<ParticlesVertex*>(&particles)) {
for (sf::Vertex v : vparticles->getParticleVertex()) {
draw_one_vertex(v, getCanvas());
}
} else if (auto* cparticles = dynamic_cast<ParticlesCircle*>(&particles)) {
for (CircleWidget& c : cparticles->getParticleCircles()) {
draw_one_circle(c, getCanvas());
}
}
// else ... ?
}
(CircleWidget is made up. I'm not familiar with sf, but that's not the point here.)
Since getParticleVertex doesn't make sense for every kind of ParticleInterface, any code that would use it from the interface will necessarily have some sort of if-like check, and a dynamic_cast to get the actual data. The drawUpdate above also isn't extensible if more types are ever needed. Even if there's a generic else which "should" handle everything else, the fact one type needed something custom hints that some other future type or a change to an existing type might want its own custom behavior at that point too. Instead, change from a thing code does with the interface to a thing the interface can be asked to do:
class ParticlesInterface {
// ...
public:
virtual void drawUpdate(CanvasWidget& canvas) = 0;
// ...
};
class ParticlesVertex {
// ...
void drawUpdate(CanvasWidget& canvas) override;
// ...
};
class ParticlesCircle {
// ...
void drawUpdate(CanvasWidget& canvas) override;
// ...
};
Now the particles classes are more "alive" - they actively do things, rather than just being acted on.
For another example, say you find ParticlesCircle, but not ParticlesVertex, needs to make some member data updates whenever the coordinates are changed. You could add a virtual void coordChangeCB() {} to ParticlesInterface and call it after each motion model tick or whenever. With the {} empty definition in the interface class, any class like ParticlesVertex that doesn't care about that callback doesn't need to override it.
Do try to keep the interface's virtual functions simple in intent, following the Single Responsibility Principle. If you can't write in a sentence or two what the purpose or expected behavior of the function is in general, it might be too complicated, and maybe it could more easily be thought of in smaller steps. Or if you find the virtual overrides in multiple classes have similar patterns, maybe some smaller pieces within those implementations could be meaningful virtual functions; and the larger function might or might not stay virtual, depending on whether what remains can be considered really universal for the interface.
(Programming best practices are advice, backed by good reasons, but not absolute laws: I'm not going to say "NEVER use dynamic_cast". Sometimes for various reasons it can make sense to break the rules.)
Suppose I have a class structure like (simplifying the actual classes I have):
class Graph
{
};
class DerivedGraph : public Graph
{
};
class DerivedGraph2 : public Graph
{
};
I want to expand this structure to account for different variations of the same graph. Ideally I would like to be able to do something like:
class Graph
{
};
// Removed
//class DerivedGraph : public Graph
//{
//};
// Removed
//class DerivedGraph2 : public Graph
//{
//};
class DerivedGraph3 : public Graph // really just a mode of DerivedGraph
{
};
class DerivedGraph4 : public Graph // really just a second mode of DerivedGraph
{
};
class DerivedGraph5 : public Graph // really just a mode of DerivedGraph2
{
};
class DerivedGraph6 : public Graph // really just a second mode of DerivedGraph2
{
};
But you can quickly see the problem here -- I am having to create too many classes here. Also, the base class is extremely complex and large (the bottom line is that it just plain sucks) ... so I don't want to make too many structural changes. I want the flexibility of defining things at the level of just the graph itself but at the same time have the flexibility of defining things for a particular mode of one graph type. I would like to be able to use virtual functions such as DoesGraphSupportNormalizedData() or something like that (this is just a simple example). Each class would then override this method.
Another idea I had was to create a separate class structure for the modes themselves (the Graph class would create an instance of it), like:
class BaseMode
{
};
class Mode1 : public BaseMode
{
};
class Mode2 : public BaseMode
{
};
Now the problem is that these mode classes need access to several pieces of data from the Graph class ... and I really don't want to pass all of that information. The mode class would then become just as useless and wouldn't be flexible at all. I just can't think of a clean way to deal with this. The best I could come up with is to have the mode classes do what it can without having to pass all kinds of crap to it but now the interface is just goofy and awkward. Any ideas?
You can either user and interface or use inherited classes from what I can gather from your description.
If you use a base-class and inherit off of it just have the things you don't want derived classes to have just give them the private access modifier and then protected or public for the others (depending on the situation of course). That way your derived classes only take what information they need. You could also have a instance variable that needs to be set in each of lower classes to define things about each derived class. Access modifiers are your friends.
If you use an interface just include everything each graph will need and then when building the individual classes just customize them from there to include the specialties.
If it were up to me, personally, I would go with inheritance over an interface but that's just me.
I ran in this kind of a problem before (and still now and then...)
In this case, you may be taking it the wrong way, what you're looking into is device a specialized function depending on the type of graph and mode. Inheritance is nice, but it has its limits as you mentioned. Especially because the user may want to switch the type of graph, but keep is existing graph object. Inheritance is not helpful in that case.
One way to do something like this is to create functions that get called depending on the current type and mode. Say you have to draw lines and the mode can be set to LINE or DOTS. You could have two functions that draw a line and are specific to a mode or another:
void Graph::draw_line_line(line l)
{
// draw a line
}
void Graph::draw_line_dots(line l)
{
// draw a dots along the line
}
Now you can define a type which represents that type of render functions and a variable member for it:
typedef void (Graph::*draw_line_func)(line l);
draw_line_func m_draw_line;
With that in hands, you can program your set_mode() function, something like this:
void Graph::set_mode(mode_t mode)
{
m_mode = mode; // save for get_mode() to work
switch(mode)
{
case LINE:
m_draw_line = &Draw::draw_line_line;
break;
case DOTS:
m_draw_line = &Draw::draw_line_dots;
break;
...
}
}
Now when you want to render the line, you do call this specialized function and you do not need to know whether it is a LINE or a DOTS...
void Graph::draw_line(line l)
{
this->*m_draw_line(l);
}
This way you create an indirection and make it a lot cleaner in the existing large functions that have large switch or many if() statements without breaking up the existing "powerful" class in many pieces that may become hard to use (because if it's that big it's probably already in use...)
I have a class,
class Ticket : public cocos2d::CCNode, public cocos2d::CCTargetedTouchDelegate { ... };
Which works fine when I register for touch events on that node using:
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(ticket_, 0, true);
However, if I alter my class so that it uses composition rather than inheritance for the CCNode bit:
class Ticket : public cocos2d::CCTargetedTouchDelegate {
private:
cocos2d::CCNode* node_;
public:
Ticket() { node_ = new CCNode(); node_->init(); }
cocos2d::CCNode* node() { return node_; }
...
};
Then the following blows up with a SIGSEGV 11:
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(ticket_, 0, true);
I have added ticket_->node() to the current layer, but I am wondering if the touch dispatcher somehow doesn't like the node and the delegate to be different things. Or to put it another way, is touch dispatcher is expecting the node and the delegate to be the same thing?
So in short, my code works when I use multiple inheritance, but it doesn't when I use composition. Without delving into the framework, can anyone say that this is true, or have I just missed something obvious? I am using cocos2d-2.1rc0-x-2.1.2
Yes, it seems cocos2d-x indeed does force multiple inheritance. It expects the touch delegate to be dynamically castable to a CCObject, which your Ticket class isn't when you use composition. When you inherit from CCNode, which itself inherits from CCObject, you're in the clear. You can see the problem here on github.
This does not seem to be a mistake though, since the documentation actually hints at this by noting
IMPORTANT: The delegate will be retained.
for CCTouchDispatcher::addTargetedDelegate.
I've been stuck for some time on this problem, and I need your help.
My C++ application is running on multiple exec sites. My problem is that I cannot pass objects holding a virtual table, because sites do not share memory (thus a virtual method from a given object will lead to an undefined behaviour). By "I cannot pass" I mean : I do not want any virtual table.
The fun thing is there's not only inheritance, but also templates and eerie conception...
Here is the code
// "Main" code
List< Animals, 5 > list;
List< Animals, 8 > list2;
list.concatenate( list2 );
// GenericList.hpp
template< Type >
class GenericList
{
virtual getBuffer(void) = 0;
virtual getSize(void) = 0;
void concatenate( GenericList<Type> gList)
{
int size = gList.getSize(); // Call to the child...
...getBuffer()...
// processing, etc.
}
}
// List.hpp
template< Type, Size_ >
class List : public GenericList< Type >
{
int getSize()
{
return Size_;
}
Type * getBuffer()
{
return buffer;
}
Type buffer[Size_];
}
How can I get rid of inheritance ?
EDIT/ In light of the first few answers, I can tell you that I cannot implement a better serialization, the code being private.
If you just want to get rid of virtual tables, you don't have to get rid of inheritance. You have to get rid of virtual functions. Looking at the code you post, maybe you can make a few changes so that getSize and getBuffer are in GenericList, so you can make them non-virtual, but that really depends on the rest of your code.
The first question is, however, why would you worry about virtual tables in the first place? When you serialize the objects, you should serialize their data in order to preserve their state, and the state is the only thing you should pass around.
I think you are blaming the wrong part of the problem there... if you have a distributed system, you have to make sure that the serialized data that is sent on the wire contains enough information to rebuild the state of the object on the other end of the connection.
I believe that the problem you are facing is that you are sending raw data over the wire, while you should have a serialization mechanism that is able to encode the actual type of the object being sent and rebuild the object on the opposite end with the exact same type. In the case of an object belonging to a class with virtual functions, that will mean that the two objects are not equal bitwise, as on each end of the connection the pointer to the vtable will refer to a different location in memory, but they will be semantically equal, which is what you need to be able to process the objects on the other end.