I'm facing a problem, a design problem. There is this template class which represent File handling/driver interface. Here is the barebone of that class.
---------------------------- FileDriver.h---------------------------
namespace DatabaseManager {
template<class T>
class FileDriver {
FileDriver(const char *file_name) : file_name(file_name) {}
public :
T* fetch(size_t rec_size, long rec_num, long offset , bool write_enabled) {
// fetch data from file
}
int insert(T *rec, size_t rec_size, long rec_num, long offset) {
// insert data into file
}
inline int release(T *rec, size_t rec_size, int rec_num) {
// close the file
}
};
}
Now this class is used by any class in the system which needs I/O operation. But as its a template class so i have to create objects of this class everytime i need to access a file. For example here is how a function uses this class.
---------------------- ParseSparseParticles.cpp ------------------
#include "FileDriver.h"
bool ParseSparseParticles::openFile() throw(ParseSparseParticlesException)
{
// DatabaseManager::FileMetaInfo is a struct containing meta information about a file
DatabaseManager::FileMetaInfo *meta_info = nullptr;
DatabaseManager::SparseParticles *particle_data = nullptr;
DatabaseManager::FileDriver<DatabaseManager::FileMetaInfo> meta_hndlr(meta_file_name.str().c_str());
meta_info = meta_hndlr.fetch(sizeof(DatabaseManager::FileMetaInfo), 1, static_cast<int>(DatabaseManager::file_map_pos::START), false);
if (meta_info) {
DatabaseManager::FileDriver<DatabaseManager::SparseParticles> data_hndlr(file_name.str().c_str());
particle_data = data_hndlr.fetch(sizeof(DatabaseManager::SparseParticles),
meta_info->num_rec, static_cast<int>(DatabaseManager::file_map_pos::START), false);
if (particle_data) {
data_hndlr.release(particle_data, sizeof(DatabaseManager::SparseParticles), meta_info->num_rec);
meta_hndlr.release(meta_info, sizeof(DatabaseManager::FileMetaInfo), 1);
return true;
} else {
throw ParseSparseParticlesException("Cannot open Sparse Particles File");
}
} else {
throw ParseSparseParticlesException("Cannot open Meta Info File");
}
}
So i have to like follow this exact same steps everytime i need to access any file.
1. Open the meta info file
2. Open the actual data file
3. Close the data file
4. Close the meta file
And this gets tiresome after sometime, worse it leads to duplicate code, unstructured code, as file operation is done all over the system. So i was thinking about making an interface that will abstract the operation of I/O. And in the process of doing so i stumbled when i wanted to create FileDriver member object of the interface class, like so
--------------------------- IOInterface.h ---------------------------
#include "FileDriver.h"
template<typename MetaFileType, typename FileType>
class IOInterface {
DatabaseManager::FileDriver<MetaFileType> meta_orb; // won't compile
DatabaseManager::FileDriver<FileType> data_orb; // won't compile
};
But this won't compile as i'm including a template header into another template header. So can please anyone tell me how to solve this problem. How can i make an class that will act like an interface to FileDriver that will store the FileDriver object as long as that class object is alive.
Thanks
UPDATE
The error i'm getting while compiling is with the IOInterface constructor.
IOInterface::IOInterface(std::string data_dir, std::string file_prefix, int id) :
data_dir(data_dir),
file_prefix(file_prefix),
file_id(id)
{}
/var/local/PolymerizationSimulation/include/IOInterface.h:7: error: no matching function for call to 'DatabaseManager::FileDriver<DatabaseManager::MetaFileType>::FileDriver()'
/var/local/PolymerizationSimulation/include/IOInterface.h:7: error: no matching function for call to 'DatabaseManager::FileDriver<DatabaseManager::FileType>::FileDriver()'
Some hints from looking at your code:
You miss semicolons after class definition:
};
^
also from your example, FileDriver is not inside DatabaseManager
In this class:
template<class T>
class FileDriver {
all members are private, even constructor, so you cannot access it. Finally this class does not provide default constructor needed by:
DatabaseManager::FileDriver<MetaFileType> meta_orb; // won't compile
DatabaseManager::FileDriver<FileType> data_orb; // won't compile
so compiler have no idea how to create those instances, add it for FileDriver:
FileDriver(){}
Related
I have two classes, in the first class, 'DrawGraphics' I am trying to access a member variable from a class that I have forward declared 'MainComponent'. However, this leads to a read access violation.
This is the error message:
Unhandled exception thrown: read access violation.
std::_Unique_ptr_base<juce::Slider::Pimpl,std::default_delete<juce::Slider::Pimpl> >::_Myptr(...) returned 0xFFFFFFFFFFFFFFFF.
I'm using the JUCE framework by the way, the exception occurs here:
_NODISCARD pointer operator->() const _NOEXCEPT
{ // return pointer to class object
return (this->_Myptr()); // <-- this is the exception breakpoint
}
what you see below is only about 20% of the actual code but I'm going to try and only include the relevant parts of each file so as not to drown you in questionably written code.
DrawGraphics.h
class MainComponent;
class DrawGraphics : public Component
{
public :
void clock();
private:
MainComponent* mainComponent;
};
DrawGraphics.cpp
#include "DrawGraphics.h"
#include "MainComponent.h"
void DrawGraphics::clock()
{
double sliderOutput = mainComponent->ampSlider.getValue();
// THIS ^ CAUSES THE ERROR
DBG("Slider output is : " << sliderOutput);
}
MainComponent.h
class MainComponent : public Component,
public Slider::Listener
{
public:
Slider ampSlider;
void sliderValueChanged(Slider* slider) override;
private:
DrawGraphics drawGraphics;
};
MainComponent.cpp
void MainComponent::sliderDragStarted(Slider* slider)
{
if (slider == &Slider)
{
drawGraphics.clock();
}
}
I was hoping to simply be able to access the data stream that is produced from ampSlider. Apologies in advance if I failed to include parts of the code that are actually relevant to the issue.
...
EDIT:
Ok so my problem was I hadn't intialised mainComponent. I did this by changing
MainComponent* mainComponent; to MainComponent* mainComponent{}; in DrawGraphics.h
and then in DrawGraphics.cpp I created an object of mainComponent by simply adding mainComponent = new MainComponent; at the start of DrawGraphics::clock()
It seemed as though when trying to get a value of ampSlider, I was referering to an empty, unitialised object.
Thanks for all the help.
MainComponent seems to be uninitialized, change to:
MainComponent* mainComponent{};
Then, before using, check for null:
if (!mainComponent) {
return;
}
//do stuff with mainComponent
Should solve the issue.
First of all, sorry for the title. I didn't know exactly how to give name to the situation I'm facing.
I am developing a project in C++ that will run over QNX (so answers that recur to Windows libraries are not good).
I have one class that holds and manipulates all my data, and a few other classes that are responsible for dealing with my UI.
The UI manipulating classes include my data class, and when they are initialized, they all get a pointer to the same data object (each one uses different parts of it, though). And the normal flow of the program is the UI receiving events from the user, and then making calls to the data class and updating itself, according to the data class replies. That all works just fine.
The problem is, sometimes it might happen that this data class object receives calls from other sorts of external events (let's say a call from a class responsible for communication), asking it to change some of it's values. After doing so, it would have to update the UI (thus, having to make a call to the UI classes).
The actual objects to all the classes (UI and data) are contained by the "main" class. But as the UI classes include the data class to be able to call it's methods, the data class including UI classes in order to be able to call their methods would fall into mutual inclusion.
The problem resumes, in a very simplistic way (I am just trying to give a visual example of the information flow), to something like this:
main.cpp
#include "interface.h"
#include "data.h"
Data data_;
Interface interface_;
// Initialize all data from files, etc
data_.Init();
// Call the interface that will use all of this data
interface_.Init(&data_);
while(1);
interface.h
#include "data.h"
class Interface
{
Data *data_;
void Init(Data *data);
void ReceiveEvent();
void ChangeScreen (int value);
};
interface.cpp
#include "interface.h"
void Interface::Init(Data *data)
{
// Get the pointer locally
data_ = data;
}
// Function called when a (for example) a touch screen input is triggered
void Interface::ReceiveEvent()
{
ChangeScreen(data_->IncreaseParam1());
}
void Interface::ChangeScreen (int value);
{
// Set the value on screen
}
data.h
class Data
{
int param 1;
void Init();
int IncreaseParam1();
void ReceiveExternalEvent();
};
**data.cpp"
#include "data.h"
void Data::Init()
{
// The value actually come from file, but this is enough for my example
param1 = 5;
}
int IncreaseParam1()
{
param1 += 5;
return param1;
}
// This is called from (for example) a communication class that has a
// pointer to the same object that the interface class object has
void ReceiveExternalEvent()
{
IncreaseParam1();
// NOW HERE IT WOULD HAVE TO CALL A METHOD TO UPDATE THE INTERFACE
// WITH THE NEW PARAM1 VALUE!
}
I hope I made myself clear enough.
Can someone please give me ideas on how to deal with this situation?
Thanks a lot in advance!
Both Data and Interface are singletons. You expect to only have one instance of each class in existence. So:
Class Data {
public:
static Data *instance;
Data()
{
instance=this;
}
// Everything else that goes into Data, etc...
};
Class Interface {
public:
static Interface *instance;
Interface()
{
instance=this;
}
// Everything else that goes into Data, etc...
};
Now, ReceiveExternalEvent() will simply invoke Data::instance->method() and/or Interface::instance->method(), and so on...
This is a classical singleton design pattern.
Also, you might find some additional Google food of likely interest to you: "model view controller" and "mvc".
I have made a big edit in attempt to clarify what help I am asking for and to try to make the question appropriate for Stack Overflow.
The problem in general: I have an existing library class which allows me to query a server for information. That library class is widely used by a large amount of legacy software, so I am somewhat limited in the changes I can make to it. Likewise, reimplementing it in a better fashion might not be time well spent.
The problem in specific: I've create a simplified "toy" model of my approach below with 3 classes. The real thing is more complex, as there are polymorphic variations, more functionality, error handling, etc.
In "toy" model code included below, Gateway is the existing library class. I've tried to show how I would like to use it, with a result set and a way to access each member of the set. The idea is similar to how a well-implemented database API might look, with a statement, result and row -- except in my case, what would be the statement class is hobbled by a poor design which includes part of the result functionality.
The toy example below will not compile as-is because of the following cyclical dependecy. The Gateway class includes the ResultSet class and depends upon it, as it returns a ResultSet object. The ResultSet class depends on the Member class, as it uses it to convert the data returned from the server into primitives (e.g. string). But the Member class refers back to the Gateway class to access that data, and so there is a cycle.
I want to find a solution which will provide the ResultSet and Member functionality.
For a simpler 2 class problem, I know a solution. It is to create a superclass that one class derives from (is-a), and which the other class is composed of (has-a), such that both original classes depend on the third, and all is right with the world. :-)
For my 3 class problem, for some reason I have been unable to wrap my head around how to refactor it to make it work.
// Gateway.h
#include "ResultSet.h"
class Gateway {
ResultSet exec(string params);
};
// Gateway.cpp
ResultSet Gateway::exec(string p) { ... }
// ResultSet.h
#include "Member.h"
class ResultSet {
ResultSet(); // ctor
int index;
bool next();
string getCurrent(Member member);
};
// ResultSet.cpp
ResultSet::ResultSet() { index = 0; }
bool ResultSet::next() { ++index < length; }
string ResultSet::getCurrent(Member member) { member.fetch(index) }
// Member.h
#include "Gateway.h"
class Member {
Gateway gateway;
string fetch(int i);
};
// Member.cpp
string Member::fetch(int i) { return gateway.sGet(i); }
// Example desired usage of the final API.
main() {
Gateway gate;
ResultSet set;
Member member;
set = gate.exec("...");
while (set.next()) {
cout << set.getCurrent(member) << endl;
}
}
The solution to your issue is to forward declare the overlapping classes in the header files, and then to include their actual .h files from your .cpp implementation files.
For instance, to get around Gateway's dependencies on ResultSet,
// Gateway.h
class ResultSet;
class Gateway {
ResultSet exec(string params);
};
This forward declares the class ResultSet.
Now in Gateway.cpp, we have to provide the actual interface to the compiler. So now we include ResultSet.h.
// Gateway.cpp
#include "ResultSet.h"
ResultSet Gateway::exec(string p) { ... }
We do this for your other cyclic relationships, and you will then have source you can compile and build.
For ResultSet, we will forward declare Member.
// ResultSet.h
class Member;
class ResultSet {
ResultSet(); // ctor
int index;
bool next();
string getCurrent(Member member);
};
And in its implementation file, we will finally include Member's header.
// ResultSet.cpp
#include "Member.h"
ResultSet::ResultSet() { index = 0; }
bool ResultSet::next() { ++index < length; }
string ResultSet::getCurrent(Member member) { member.fetch(index) }
And finally, Member...
// Member.h
class Gateway;
class Member {
Gateway gateway;
string fetch(int i);
};
And of course, Member.cpp must then include Gateway's information.
// Member.cpp
#include "Gateway.h"
string Member::fetch(int i) { return gateway.sGet(i); }
Now there are no cyclic dependencies.
I am trying to write a message handler whose Base classes are
1-Handler base class
2-Handler Factory that generates proper handler for a proper message type
3-and a base generic class for message
their code is like this:
#include <map>
#include<iostream>
//Base Handler
template<class MSG>
class Handler
{
MSG message;
public:
Handler(MSG message):message(message){
}
virtual void handle() = 0;
MSG getMessage()
{
return message;
}
};
//Base Handler Factory
template<class MSG>
class HandlerFactory {
public:
virtual Handler<MSG> * create(MSG & message) = 0;
};
//Base message
template<class T>
class Message
{
T messageType;
public:
T getMessageType()
{
return messageType;
}
void setMessageType(T messageType_)
{
messageType = messageType_;
}
};
//Then, based on the message type, I write subclass for every base class:
//my custom types
enum MessageType
{
ANNOUNCE,
KEY_SEND,
KEY_REQUEST
};
//my first custom message format
class MyMessage_1 : public Message<MessageType>
{
//...
};
//my first custom handler
class MyMessageHandler_1 : public Handler<MyMessage_1>
{
public:
MyMessageHandler_1(MyMessage_1 &message_): Handler<MyMessage_1>(message_)
{
}
void handle(){}
};
//my custom handler factory
class MyHandlerFactory : public HandlerFactory<Message<MessageType> > {
Handler<Message<MessageType> > *value;
public:
MyHandlerFactory(){};
Handler<Message<MessageType> > * create(Message<MessageType> & message){
switch (message.getMessageType())
{
case ANNOUNCE:
MyMessage_1 t1;
value = new MyMessageHandler_1(t1);//error here
break;
//etc. etc.
default:
value = 0;
break;
};
return value;
};
};
//let's put a main so you can easily compile it
int main()
{
}
the problem is when, in switch-case clause, I try to create an instance of a handler for one of my custom message classes, I get the following error:
templateArgList.cpp: In member function ‘virtual Handler<Message<MessageType> >* MyHandlerFactory::create(Message<MessageType>&)’:
templateArgList.cpp:86:37: error: cannot convert ‘MyMessageHandler_1*’ to ‘Handler<Message<MessageType> >*’ in assignment
I was under the impression that:
Handler<Message<MessageType> > * can be casted as follows:
MyMessageHandler_1-> Handler<MyMessage_1>
^
|
`Message<MessageType>` which finally gives me:
`Handler<Message<MessageType> >` :P
Am I wrong? of course I am, why would I get the above error then :))
I just don't know why and how to fix it.
Therefore I will appreciate if you kindly help me with it.
thanks very much for your kind help
Here is a very simple program that is analogous to what you have done, but without the nested templates so that it's understandable:
#include <vector>
class A {
};
class B : public A {
};
int main() {
std::vector<A>* va;
va = new std::vector<B>;
}
And indeed, g++ gives the error:
error: cannot convert ‘std::vector<B>*’ to ‘std::vector<A>*’ in assignment
This should be clear -- a vector of A's is not the same as a vector of B's, even though B inherits from A. To be able to take advantage of inheritance, you have to have pointers to the objects that are related. For example:
int main() {
std::vector<A*> va(3);
for (int i=0; i<3; ++i) {
va[i] = new B;
}
}
The analogy here is:
std::vector< > ----> Handler< >
A ----> Message<MessageType>
B ----> MyMessage_1
By the way, did you realize that you define a variable named message in both MyMessageHandler_1 and also in Handler<>? This will cause MyMessageHandler_1::message to hide Handler<>::message. I'm not sure if this is what you want.
Also.. you might want to look into the Twisted package for Python, as it might be well suited to the application you're building. (If you don't mind using Python.)
Question: "any suggestion to alter my code?"
Response:
Well, I would try removing the templates and enjoying the power of inheritance. The Handler class can accept a Message object (or reference or pointer), as both of these are base classes. The HandlerFactory's create would also accept a Message object. Then you can proceed with the Message class having an enum MessageType type member variable and using switch inside HandlerFactor to determine the correct Handler-derived class to create.
Or instead of the enum, you could exploit inheritance even further by adding a "NewHandler()" function to Message, which would be pure virtual in Message and would be defined in the derived class. This way, you wouldn't need a switch -- each type of message knows what Handler it needs, and the factor simply calls message->NewHandler().
...It's a bit difficult to determine whether you need to use templates or not because I'm not sure where your project is headed. However, as a rough rule of thumb, it's a good idea to use templates when (a) you want to use equivalent blocks of code for different types and (b) you can't use inheritance to accomplish it. The std::vector<> is a good example -- the behavior of std::vector<int> and std::vector<float> is the same, but int's and float's aren't related by any common base, so rather than rewrite the code for a VectorI and VectorF, the compiler is asked to rewrite the code instead.
So far, it looks like you can exploit inheritance to do what you want. It has the added bonus of making it easier for other people to read your code, as well. :)
I've got a class outputInterface; that should handle the output (to files) of some data. The data is contained in objects of some custom classes, say dataClassA and dataClassB, that all derive from a common base class dataClassBase.
Now I want the data to be written to different files according to its type. So data of type dataClassA should go to fileA, data of type dataClassB should go to fileB and so on. As this output happens very often I would like the file handles (fileA and fileB) to stay open, i.e. I don't want to open and close the files for the output of each piece of data. One outputInterface object can be expected to exist all the time.
So what I would like to achieve is something like this:
Dynamically associate data of type dataClassA with the file handle fileA etc.
When receiving data of type dataClassA check whether fileA is already connected to a file, if not, open the file.
How can I get this behavior (or least something similar / better)?
I've been thinking of making the file handles static members of dataClassA and dataClassB (or the base class dataClassBase?). But then, how do I take care of closing the files? I would have to somehow keep track of the data types that have actually been used (the files that have actually been opened).
Try something like this:
#ifndef OUTPUTINTERFACE?H
#define OUTPUTINTERFACE?H
#include <string>
#include <fstream>
#include <map>
class DataClass
{
public:
virtual bool WriteData(std::ofstream& FStream) = 0;
};
class DataClass1 :
public DataClass
{
virtual bool WriteData(std::ofstream& FStream)
{
FStream << "teletubbies";
}
};
class DataClass2 :
public DataClass
{
virtual bool WriteData(std::ofstream& FStream)
{
FStream << "garbage";
}
};
class OutputInterface
{
public:
OutputInterface()
{
}
~OutputInterface()
{
//Release stream pointers
}
template<typename T>
bool WriteData(T& Data)
{
std::string dClassUID = std::string(typeid(T).name);
tFStreamMap::iterator it this->streamMap.find(dClassUID);
std::ofstream* stream = NULL;
if(it != streamMap.end())
{
stream = it->second;
}
else
{
stream = new std::ofstream();
stream->open(dClassUID + ".txt");
streamMap.insert(std::make_pair(dClassUID, stream));
}
Data.WriteData(stream);
}
private:
typedef std::map<std::string, std::ofstream*> tFStreamMap;
tFStreamMap streamMap;
};
#endif
This is just a prove of concept and can be optimized in many ways.
I would rather stick with overloaded functions than with runtime type checks.
This is fairly easy to implement in C++11, using an
std::map<std::type_index, std::ostring*> outputMap. (In C++03, you'll have to
implement the equivalent of std::type_index yourself.) You get the
output stream using outputMap[typeid(*data)]. The only problem is
getting the streams into the map to begin with: you can do something
like:
std::ostream*& destPtr = outputMap[typeid(*data)];
if ( destPtr == NULL ) {
destPtr = new std::ofstream("...");
}
std::ostream& dest = *destPtr;
But from where do you get the filename?
There's also the question of when you close the streams: you can't
normally close an output stream in a destructor, since closing an output
stream is an operation which can fail, and you need to detect and react
to that failure. Probably with an exception, which is why you don't
want to do it in a destructor.
Since the "data" part comes from dataClassBase, you can make a virtual/pure-virtual function 'WriteData` in this class, and let derive class implement it.
The class outputInterface may take objects of type dataClassBase and would directly call WriteData. Other than WriteData you may also add other virtual functions in dataClassBase
You did not mention relationship between outputInterface and dataClassBase