I have two classes: Parent and Derived. I want to achieve ability to save and read them from/to binary file, or transfer them. Please help with idea or code snippets how do it.
class Parent {
public:
virtual int func1(){ return 1; }
virtual unsigned func2() = 0;
std::string asd;
}
class Derived : public Parent {
public:
unsigned func2(){ return 2; }
bool boo;
}
Save to binary file
Parent *obj = new Derived;
write_to_file( obj, sizeof(*obj) );
Then read from file
read_from_file( obj, sizeof(*obj) );
But this method will overwrite pointers to virtual functions. So I need to create POD class without virtuals to save it and to read from file. Right? Create reflected POD class for every Derived seems not good idea.
There is no direct answer to this question. You should use serialization. C++ has no native serializers, as Java or C#. But there are a lot of open-source serializers over the internet. For example boost::serialization, s11n, and many others.
Related
I have a class representing some parameter. The parameter can be number, array, enum or bitfield - this is the param type. The behavior is slightly different between these types, so they are subclasses of paramBase class. The parameter can be stored in RAM or be static (i.e. hardcoded in some way, currently saved in a file).
void read() implemented in paramBase and uses template method pattern to implement reading for any param type, but this works only for RAM storage. If parameter is static then read() must be completely different (i.e. read from file).
A straightforward solution can be further subclassing like paramArrayStatic, paramNumberStatic, etc. (it will be 8 subclasses).
The difference between paramArray and paramArrayStatic is basically only in the read() method, so a straightforward solution will lead to code duplication.
Also I can add if( m_storage==static ) to read() method and modify behavior, but this is also code smell(AFIK).
class paramBase
{
public:
virtual paramType_t type() = 0;
paramStorage_t storage();
virtual someDefaultImplementedMethod()
{
//default implementation
}
void read()
{
//template method pattern
m_prop1 = blablabla;
someDefaultImplementedMethod();
}
protected:
paramStorage_t m_storage;
int m_prop1;
int m_prop2;
};
class paramArray: public paramBase
{
public:
virtual paramType_t type()
{
return PT_ARRAY;
}
virtual someDefaultImplementedMethod()
{
//overriding default implementation of base
//i.e. modify templated read() method behavior
}
protected:
int m_additional_prop1;
int m_additional_prop2;
};
In the end, I have 4 subclasses of base and I need to modify behavior of read() by static/non_static modificator.
How do I solve this without code duplication and code smell? Is the condition if( m_storage==static ) in read() is code smell or not?
You never have to duplicate code: just only re-implement that single method read. If you need to use it from pointers to the base class, virtual does just that. If you have common code between that 8 read method (or just between some of them), put it in a common middle layer.
If you want to make it clear that the class might not use the method at the base level, you can make it abstract, the add a ninth subclass for the RAM case.
Having a huge switch calling 9 different read methods in the same class seems far worse to me.
Straightforward solution can be furhter subclassing like paramArrayStatic, paramNumberStatic..etc. i.e. totally it will be 8 subclasses. Difference between paramArray and paramArrayStatic is basically only in read() method, so straightforward solution will lead to code duplication.
I agree. Creating a class that overrides the behaviour in such a significant way would be in violation of the SOLID principles (specifically the LSP part).
Also i can add if( m_storage==static ) to read() method and modify behavior, but this is also code smell(AFIK).
Who decides that this is code smell? It seems most expressive, and sensible to me.
Stop worrying so much about code smells, and start questioning the expressiveness of your options...
SigmaN,
For your simple example I would not worry about the control coupling in the read method. It is often better to have clear and maintainable code versus code that is strictly decoupled.
The general idea of your questions seems to be about decoupling the source of a value from the business logic for that value. Oftentimes, a good strategy is creating an interface as an ABC and then taking an instance on the the ctor. Here is a very simple example.
class ReadValue
{
public:
virtual int32_t readValue(std::string & value) = 0;
};
class DatabaseReadValue::public ReadValue
{
public:
virtual int32_t readValue(std:string & value) override; // read from the database
}
class XMLReadValue::public ReadValue
{
public:
virtual int32_t readValue(std::string & value) override; // read from XML file
}
class Parameter
{
public:
Parameter(ReadValue & readValueObj): readValueObj_(readValueObj) {}
int32_t read() { return(readValueObj_.readValue(value_)); }
ReadValue & readValueObj_;
std::string value_;
}
Oftentimes, the idea will be used in a template class rather than using inheritance. The gist is the same however.
The idea is related several Design Patterns depending on the details. Bridge, Adapter, Factory, Abstract Factory, PIMPL.
https://en.wikipedia.org/wiki/Software_design_pattern
--Matt
My problem is solved in this way:
//public interface and basic functionality
class base
{
public:
virtual void arraySize() //part of interface
{
printf("base arraySize()\n");
}
//template method read
int read()
{
readImpl();
}
protected:
virtual void readImpl() = 0;
};
//only base functionality of array is here. no read implementation!
class array : public base
{
public:
virtual void arraySize()
{
printf("array arraySize()\n");
}
};
//implement static read for array
class stat_array : public array
{
public:
void readImpl()
{
printf("stat_array read() \n");
}
};
//implement non static read for array
class nostat_array : public array
{
public:
void readImpl()
{
printf("nostat_array read() \n");
}
};
//test
stat_array statAr;
nostat_array nonstatAr;
base *statArPtr = &statAr;
base *nonstatArPtr = &nonstatAr;
void main()
{
statArPtr->read();
nonstatArPtr->read();
}
I have a very complicated code structure, but the important bits are:
typical setup: I have a base class and two classes that derive from this base class and each has own members, and which don't have a standard constructor
class BaseSolver{
...
};
class SolverA : BaseSolver{
public:
std::string a;
SolverA(TypeA objectA);
};
class SolverB : BaseSolver{
public:
int b;
SolverB(TypeB objectB);
};
Now I have a config xml file from which I read whether I have to use SolverA or SolverB. Therefore I have an IOService:
template<class T>
class IOService
{
BaseSolver* getSolver()
{
std::string variableThatIReadFromXML;
/* here I have to perform many actions before I can create a solver object
* to retrieve the data needed for the constructors */
TypeA variableIConstrucedWithDataFromXML;
TypeB anotherVariableIConstrucedWithDataFromXML;
if (variableThatIReadFromXML == "a")
return new SolverA(variableIConstrucedWithDataFromXML); // I know that this can leak memory
else if (variableThatIReadFromXML == "b")
return new SolverB(anotherVariableIConstrucedWithDataFromXML);
}
};
And somewhere in my application (for simplicity let's say it's the main.cpp):
int main(){
IOService ioService;
BaseSolver* mySolver = ioService.getSolver();
}
That is absolutely fine.
But now, in the main I have to access the members of the derived classes a and b respectively.
How can I do this?
I thought of retreving only the type of the Solver from the IOService:
class IOService
{
decltype getSolverType()
{
std::string variableThatIReadFromXML;
/* here I have to perform many actions before I can create a solver object
* to retrieve the data needed for the constructors */
TypeA variableIConstrucedWithDataFromXML;
TypeB anotherVariableIConstrucedWithDataFromXML;
if (variableThatIReadFromXML == "a")
return new SolverA(variableIConstrucedWithDataFromXML); // I know that this can leak memory
else if (variableThatIReadFromXML == "b")
return new SolverB(anotherVariableIConstrucedWithDataFromXML);
}
TypeA getConstructorDataForSolverA()
{
/* here I have to perform many actions before I can create a solver object
* to retrieve the data needed for the constructors */
return variableIConstrucedWithDataFromXML;
}
TypeB getConstructorDataForSolverB()
{
/* here I have to perform many actions before I can create a solver object
* to retrieve the data needed for the constructors */
return anotherVariableIConstrucedWithDataFromXML;
}
};
But of course I can't specify decltype as return value.
I'm really helpless. I would appreciate any hint into the right direction, or even a solution for this problem.
[Edit]: The derived solver classes need more than only the information from the xml file to work properly. That means, that I have to set some more properties which come from a mesh file. So I could give the meshfile to the IOService, so that the IOService could set the appropriate members this way:
class IOService
{
BaseSolver* getSolver(MeshType myMesh)
{
std::string variableThatIReadFromXML;
/* here I have to perform many actions before I can create a solver object
* to retrieve the data needed for the constructors */
TypeA variableIConstrucedWithDataFromXML;
TypeB anotherVariableIConstrucedWithDataFromXML;
if (variableThatIReadFromXML == "a")
{
auto solverA = new SolverA(variableIConstrucedWithDataFromXML); // I know that this can leak memory
solverA.a = mesh.a;
}
else if (variableThatIReadFromXML == "b")
{
auto solverB = new SolverB(anotherVariableIConstrucedWithDataFromXML);
solverB.b = mesh.b;
}
}
};
But then the IOService needs to know the class MeshType, what I want to avoid, because I think that it breaks encapsulation.
So I wanted to set the member a and b, respectively, in another part of my program (here for simplicity in the main).
Taking this into account, only the answer from Daniel Daranas seems like a solution for me. But I wanted to avoid dynamic casts.
So a reformulated question could be: How should I change my design to ensure encapsulation and avoid dynamic casts? [/Edit]
I am using clang 3.4 ob ubuntu 12.04 lts.
Use dynamic_cast to try to cast a pointer-to-base-class to pointer-to-derived-class. It will return NULL if the pointed-to object of the base class does not exist (NULL value of the base pointer), or is not actually a derived class object. If the result, instead, is not NULL, you have a valid pointer-to-derived-class.
int main(){
IOService ioService;
BaseSolver* mySolver = ioService.getSolver();
SolverB* bSolver = dynamic_cast<SolverB*>(mySolver);
if (bSolver != NULL)
{
int finallyIGotB = bSolver->b;
cout << finallyIGotB;
}
}
Note that there may be some better design solutions than using dynamic_cast. But at least this is one possibility.
The funny thing about polymorphism is that it points out to you when you are not using it.
Inheriting a base class in the way you are serves 1 purpose: to expose a uniform interface for objects with different behaviors. Basically, you want the child classes to look the same. If I have classes B and C that inherit from A, I want to say "do foo" to the class, and it'll do foob or fooc.
Essentially, you're flipping it around: I have a B and C of type A, and if it is B i want to do foob and if it is C I want to do fooc. While this may seem scary, usually the best way to solve the problem is to rephrase the question.
So to your example, you are currently saying "OK, so I have an XML file, and I will read data from it one way if I'm making an A, or another way if I'm making a B." But the polymorphic way would be "I have an XML file. It tells me to make an A or a B, and then I tell the instance to parse the XML file".
So one of the ways to solve this to change your solver interface:
class BaseSolver
{
public:
virtual void ReadXMLFile(string xml) = 0;
...
};
While this does rephrase the problem in a way that uses polymorphism, and removes the need for you to see what you've created, you probably don't like that for the same reason I don't: you'd have to supply a default constructor, which leaves the class in an unknown state.
So rather than enforce it at the interface level, you could enforce it at the constructor level, and make both SolverA and SolverB have to take in the XML string as part of the constructor.
But what if the XML string is bad? Then you'd get an error state in the constructor, which is also a no-no. So I'd deal with this using the factory pattern:
class SolverFactory;
class BaseSolver
{
public:
virtual void solve() = 0;
protected:
virtual int ReadXML(std::string xml) = 0;
friend class SolverFactory;
};
class A : public BaseSolver
{
public:
virtual void solve() {std::cout << "A" << std::endl;}
protected:
A(){}
virtual int ReadXML(std::string xml) {return 0;}
friend class SolverFactory;
};
class B : public BaseSolver
{
public:
virtual void solve() {std::cout << "B" << std::endl;}
protected:
B(){}
virtual int ReadXML(std::string xml) {return 0;}
friend class SolverFactory;
};
class SolverFactory
{
public:
static BaseSolver* MakeSolver(std::string xml)
{
BaseSolver* ret = NULL;
if (xml=="A")
{
ret = new A();
}
else if (xml=="B")
{
ret = new B();
}
else
{
return ret;
}
int err = ret->ReadXML(xml);
if (err)
{
delete ret;
ret = NULL;
}
return ret;
}
};
I didn't put any actual XML processing in here because I am lazy, but you could have the factory get the type from the main tag and then pass the rest of the node in. This method ensures great encapsulation, can catch errors in the xml file, and safely separates the behaviors you are trying to get. It also only exposes the dangerous functions (the default constructor and ReadXMLFile) to the SolverFactory, where you (supposedly) know what you are doing.
Edit: in response to the question
The problem you've stated is "I have a B and C of type A, and if is B i want to set "b" settings and if it is C i want to set "c" settings".
Taking advantage of polymorphism, you say "I have a B and C of type A. I tell them to get their settings."
There a couple of ways to do this. If you don't mind mangling your IO with the class, you can simply expose the method:
class BaseSolver
{
public:
virtual void GetSettingsFromCommandLine() = 0;
};
And then create the individual methods for each class.
If you do want to create them separate, then what you want is polymorphism in the io. So expose it that way:
class PolymorphicIO
{
public:
virtual const BaseSolver& get_base_solver() const = 0;
virtual void DoSettingIO() = 0;
};
an example implmentation
class BaseSolverBIO : PolymorphicIO
{
public:
virtual const BaseSolver& get_base_solver() const {return b;}
virtual void DoSettingIO() { char setting = get_char(); b.set_b(setting);}
private:
BaseSolverB b;
};
At first glance this seems like a lot of code (we've doubled the number of classes, and probably need to supply a factory class for both BaseSolver and the IO interface). Why do it?
It is the issue of scaleability/maintainability. Lets say you have figured out a new solver you want to add (D). If you are using dynamic cast, you have to find all the places in your top level and add a new case statement. If there is only 1 place, then this is pretty easy, but if it is 10 places, you could easily forget one and it would be hard to track down. Instead, with this method you have a separate class that has all the specific IO functionality for the solver.
Lets also think of what happens to those dynamic_cast checks as the number of solvers grows. You've been maintaining this software for years now with a large team, and lets say you've come up with solvers up to the letter Z. Each of those if-else statements are hundreds-a tousand of lines long now: if you have an error in O you have to scroll through A-M just to find the bug. Also, the overhead for using the polymorphism is constant, while reflection just grows and grows and grows.
The final benefit for doing it this way is if you have a class BB : public B. You probably have all the old settings from B, and want to keep them, just make it a little bigger. Using this model, you can extend the IO class as well for the io for BB and reuse that code.
One way to achieve this is to add an interface method into the base class:
class BaseSolver{
virtual void SolverMethodToCallFromMain() = 0;
...
};
class SolverA : BaseSolver{
public:
std::string a;
SolverA(TypeA objectA);
virtual void SolverMethodToCallFromMain() {/*SolverA stuff here*/};
};
class SolverB : BaseSolver{
public:
int b;
SolverB(TypeB objectB);
virtual void SolverMethodToCallFromMain() {/*SolverB stuff here*/};
};
And in main:
int main(){
IOService ioService;
BaseSolver* mySolver = ioService.getSolver();
mySolver->SolverMethodToCallFromMain();
}
class YourInterface {
public:
YourInterface(){
}
virtual ~YourInterface(){
}
virtual void saveData(Data data) = 0; //Pure virtual = Childs are forced to implement those functions to become non abstract
virtual Data loadData() = 0;
};
//One implementation to load and save data to/from a xml file
class XmlImplementation : public YourInterface {
public:
XmlImplementation(){
}
virtual ~XmlImplementation(){
}
//Overriding functions:
void saveData(Data data){
//Save data to a xml file here
}
Data loadData(){
//Load data from a xml file here
}
};
void main(){
YourInterface* p;
p = (YourInterface*) new XmlImplementation();
p->loadData(); //We just want to get our Data here, we dont care whether its from a xml or binary file etc.
}
Please take that as an example, I know it is not good but I can't write any better than that.
I'd like to know better why the cast in main refuses to work properly ? and it has been suggested as an errorful cast.
Nothing wrong with the code, except that the cast is actually unnecessary. The code would compile and work fine without it.
There's no need for the (C-style or otherwise) cast here. Your main() function (which should always return int) should look like this:
int main()
{
YourInterface* p = new XmlImplementation();
p->loadData();
}
If you're getting an error, it's not because of the cast.
N.B: In C++, it's customary to use static_cast when typecasting from a pointer to a derived class to a pointer to a base class.
I have been developing this class for loading plugins in the form of shared objects for an application. I currently have thought of 2 ways of loading the file names of all the plugins to be loaded by the app. I have written an interface for loading file names. I have a few questions about how to improve this design. Please help. Thanks.
EDIT: Code change per feedback :D.
#include "Plugin.h"
//This class is an interface for loading the list of file names of shared objects.
//Could be by loading all filienames in a dir, or by loading filenames specified in a file.
class FileNameLoader
{
public:
virtual std::list<std::string>& LoadFileNames() = 0;
};
class PluginLoader
{
public:
explicit PluginLoader(LoadingMethod, const std::string& = "");
virtual ~PluginLoader();
virtual bool Load();
virtual bool LoadPlugins(FileNameLoader&);
virtual bool LoadFunctions();
protected:
private:
explicit PluginLoader(const PluginLoader&);
PluginLoader& operator=(const PluginLoader&);
bool LoadSharedObjects();
list<std::string> l_FileNames;
list<PluginFunction*> l_Functions;
list<Plugin*> l_Plugins;
};
Anything that seems ugly still? Thanks for the feedback anyway.
It looks to me like you have your functionality spread across the enum, FileNameLoader, and the PluginLoader classes.
My suggestion would be to make a PluginLoaderByFile class, and a PluginLoaderByDir class - possibly with one inheriting from another, or possibly with a common base class. This way you can define other subclasses including the necessary additional code, and keep it encapsulated, if necessary, down the track.
This also makes it easier to use e.g. the factory or builder patterns in future.
You created a fine interface, but then you don't use it. And you then store the file names in a private member l_FileNames.
I would change the PluginLoader constructor to accept a FileNameLoader reference and use that reference to load file names. This way you won't need the LoadingMethod in the PluginLoader class.
Write two classes that implement the FileNameLoader interface, one for each loading method.
edit:
class FileNameLoader
{
public:
//RVO will work right? :D
virtual std::list<std::string>& LoadFileNames() = 0;
};
class FileNameLoaderByFile : public FileNameLoader
{
public:
std::list<std::string>& LoadFileNames()
{
// ...
}
}
class FileNameLoaderByDirectory : public FileNameLoader
{
public:
std::list<std::string>& LoadFileNames()
{
// ...
}
}
class PluginLoader
{
public:
explicit PluginLoader(FileNameLoader& loader)
{
fileNames = loader.LoadFileNames()
}
virtual ~PluginLoader();
private:
list<std::string> fileNames;
};
As for your statement of the current problem.
U can use either
vector for params or
since u are using a string u can as well parse it using some delimiter (say " ", ",")
However I wouldn't let the params or method of loading be visible in the PluginLoader.
Instead would use a common/generic interface.
I feel like the answer to this question is really simple, but I really am having trouble finding it. So here goes:
Suppose you have the following classes:
class Base;
class Child : public Base;
class Displayer
{
public:
Displayer(Base* element);
Displayer(Child* element);
}
Additionally, I have a Base* object which might point to either an instance of the class Base or an instance of the class Child.
Now I want to create a Displayer based on the element pointed to by object, however, I want to pick the right version of the constructor. As I currently have it, this would accomplish just that (I am being a bit fuzzy with my C++ here, but I think this the clearest way)
object->createDisplayer();
virtual void Base::createDisplayer()
{
new Displayer(this);
}
virtual void Child::createDisplayer()
{
new Displayer(this);
}
This works, however, there is a problem with this:
Base and Child are part of the application system, while Displayer is part of the GUI system. I want to build the GUI system independently of the Application system, so that it is easy to replace the GUI. This means that Base and Child should not know about Displayer. However, I do not know how I can achieve this without letting the Application classes know about the GUI.
Am I missing something very obvious or am I trying something that is not possible?
Edit: I missed a part of the problem in my original question. This is all happening quite deep in the GUI code, providing functionality that is unique to this one GUI. This means that I want the Base and Child classes not to know about the call at all - not just hide from them to what the call is
It seems a classic scenario for double dispatch. The only way to avoid the double dispatch is switching over types (if( typeid(*object) == typeid(base) ) ...) which you should avoid.
What you can do is to make the callback mechanism generic, so that the application doesn't have to know of the GUI:
class app_callback {
public:
// sprinkle const where appropriate...
virtual void call(base&) = 0;
virtual void call(derived&) = 0;
};
class Base {
public:
virtual void call_me_back(app_callback& cb) {cb.call(*this);}
};
class Child : public Base {
public:
virtual void call_me_back(app_callback& cb) {cb.call(*this);}
};
You could then use this machinery like this:
class display_callback : public app_callback {
public:
// sprinkle const where appropriate...
virtual void call(base& obj) { displayer = new Displayer(obj); }
virtual void call(derived& obj) { displayer = new Displayer(obj); }
Displayer* displayer;
};
Displayer* create_displayer(Base& obj)
{
display_callback dcb;
obj.call_me_back(dcb);
return dcb.displayer;
}
You will have to have one app_callback::call() function for each class in the hierarchy and you will have to add one to each callback every time you add a class to the hierarchy.
Since in your case calling with just a base& is possible, too, the compiler won't throw an error when you forget to overload one of these functions in a callback class. It will simply call the one taking a base&. That's bad.
If you want, you could move the identical code of call_me_back() for each class into a privately inherited class template using the CRTP. But if you just have half a dozen classes it doesn't really add all that much clarity and it requires readers to understand the CRTP.
Have the application set a factory interface on the system code. Here's a hacked up way to do this. Obviously, apply this changes to your own preferences and coding standards. In some places, I'm inlining the functions in the class declaration - only for brevity.
// PLATFORM CODE
// platformcode.h - BEGIN
class IDisplayer;
class IDisplayFactory
{
virtual IDisplayer* CreateDisplayer(Base* pBase) = 0;
virtual IDisplayer* CreateDisplayer(Child* pBase) = 0;
};
namespace SystemDisplayerFactory
{
static IDisplayFactory* s_pFactory;
SetFactory(IDisplayFactory* pFactory)
{
s_pFactory = pFactory;
}
IDisplayFactory* GetFactory()
{
return s_pFactory;
}
};
// platformcode.h - end
// Base.cpp and Child.cpp implement the "CreateDisplayer" methods as follows
void Base::CreateDisplayer()
{
IDisplayer* pDisplayer = SystemDisplayerFactory::GetFactory()->CreateDisplayer(this);
}
void Child::CreateDisplayer()
{
IDisplayer* pDisplayer = SystemDisplayerFactory::GetFactory()->CreateDisplayer(this);
}
// In your application code, do this:
#include "platformcode.h"
class CDiplayerFactory : public IDisplayerFactory
{
IDisplayer* CreateDisplayer(Base* pBase)
{
return new Displayer(pBase);
}
IDisplayer* CreateDisplayer(Child* pChild)
{
return new Displayer(pChild);
}
}
Then somewhere early in app initialization (main or WinMain), say the following:
CDisplayerFactory* pFactory = new CDisplayerFactory();
SystemDisplayFactory::SetFactory(pFactory);
This will keep your platform code from having to know the messy details of what a "displayer" is, and you can implement mock versions of IDisplayer later to test Base and Child independently of the rendering system.
Also, IDisplayer (methods not shown) becomes an interface declaration exposed by the platform code. Your implementation of "Displayer" is a class (in your app code) that inherits from IDisplayer.