C++ calling constructor to initialize an object yields errors - c++

What's wrong with this:
struct FileListItem {
string sOriginalFn;
time_t ttTimeTaken;
FileListItem(){}
FileListItem(string _sOriginalFn, time_t _ttTimeTaken) :
sOriginalFn (_sOriginalFn), ttTimeTaken (_ttTimeTaken) { }
};
struct FileList : vector<FileListItem> {
int iCurItm;
FileList() : vector(), iCurItm(-1) {};
void Add(string _sOriginalFn, time_t _ttTimeTaken) {
push_back(FileListItem(_sOriginalFn, _ttTimeTaken));
}
}
I get a run-time "read access violation" the first time Add is called.
I then try:
struct FileList : vector<FileListItem> {
int iCurItm;
FileList() : vector(), iCurItm(-1) {};
FileListItem Itm; // <--- new member
void Add(string _sOriginalFn, time_t _ttTimeTaken) {
Itm(_sOriginalFn, _ttTimeTaken); // <--- E0980 pointing to "Itm"
push_back(Itm);
}
}
and get a compile time error:
E0980 - call of an object of a class type without appropriate operator() or conversion functions to pointer-to-function type.
I must have forgotten or missed something since I stopped programming 30 years ago, when Borland C++ was IT...

In the line
Itm(_sOriginalFn, _ttTimeTaken);
You are not calling the constructor for your object. Instead, the compiler interprets this as a function call on the functor Itm. Therefore, it tries to find a valid operator() for the given arguments, to no-avail.
Do not use constructor member initializer list syntax elsewhere than... Constructor member initializer list. Instead, what you have to do here is to assign a new object to your member.
Then, you don't want, ever to inherit from std containers. Their destructor is not virtual so you are exposing yourself to a realm of suffering...
Use composition or type aliasing instead:
struct FileList {
std::vector<FileListItem> flist;
int curItem;
FileList() : flist(), curItem(-1) {}
void Add(string const& _sOriginalFn, time_t _ttTimeTaken) {
// No need to construct the object before, let vector handle it
flist.emplace_back(_sOriginalFn, _ttTimeTaken);
};
As for the read access violation, from the code I see, nothing explains it. Could it be some access related to curItem somewhere in your code that isn't displayed here?

Related

C++ Class vector error, expression must have pointer type

Currently learning some c++ and unsure why this is giving me "expression must have pointer type".
Mapp.hpp
class RouteMap
{
public:
RouteMap();
string getCurrent_();
void StoreCity(string b);
private:
std::vector<string>* cities();
string current_;
};
mapp.cpp
RouteMap::RouteMap(){}
string RouteMap::getCurrent_()
{
return current_;
}
void RouteMap::StoreCity(string b)
{
cities->push_back(b); //Error
}
std::vector<string> RouteMap::cities()
{
return std::vector<string>();
}
I am attempting to have a vector Cities as a private member so that when I run the member function StoreCity(string x), it would push_back the specific string into Cities.
I'm going to take a stab and say that the problem is cities() is a function and requires parenthesis:
cities()->push_back(b);
Edit Just found the implementation of cities() (silly me). You have another problem, and that is that your declaration and implementation don't match.
// declaration
std::vector<string>* cities();
// implementation. Notice the lack of a pointer type return
std::vector<string> RouteMap::cities()
{
return std::vector<string>();
}
It's also weird that you're returning a new vector each time. You probably want a member variable:
class RouteMap
{
//...
private:
std::vector<string> my_cities;
//...
};
and then return the member variable from there:
std::vector<string>* RouteMap::cities()
{
return &my_cities;
}
Edit2: It has come to my attention that you probably, while you could fix these things like this and get it working, the truth is that you probably don't mean for cities() to be a function at all. You probably mean for it to be a member variable instead:
class RouteMap
{
//...
private:
std::vector<string> cities;
//...
};
This requires no implementation, (aka RouteMap::cities(){}), and you can just use it inside any member function (because it's a private member) like current_.

How to delete a pointer after cast to void* and back

As part of a "message"-class I try to transfer pointers of different types by casting them to void*-pointers and saving them in a wrapper class ("MsgData") that remembers the original type of the pointer.
For example a bool pointer:
bool* data = new bool;
event.wheel.y < 0 ? *data = false : *data = true;
send("all", this, MSG_MOUSE_SCROLL, MsgData(data));
The compatible Constructor of MsgData is called and the variable is saved as a member of my message class:
MsgData(): type_(NULLPTR), data_(nullptr) {} // Null
MsgData(const bool* data): type_(BOOL), data_((void*)data) {} // Bool
MsgData(const std::string* data): type_(STRING_STD), data_((void*)data) {} // std::string
// ... etc.
I can cast the pointers back and use them without any errors but when I try to delete them the program crashes:
~MsgData() {
switch (type_) {
case (BOOL):
if ((bool*)data_)
delete (bool*)data_;
break;
// ... etc.
}
}
The bool pointer is just an example and the same happens with all other types and classes too.
The program crashes only when I try to delete the pointer. Casting them back to their original type and using them is not a problem.
I researched the problem and found similar question like this one on StackOverflow but while it seems to be considered bad style to cast a pointer to void* and back I cannot find the reason why the program crashes.
Well, a better solution to the problem is to use boost::variant (or std::variant). Once you start using that, all the headache of deleting and managing type and data will go automatically. You're not the first to face of a problem of this kind; many others have faced it, and the solution is available in the form of boost::variant or std::variant.
Anyway, since you're developing a solution yourself, here is my advise: construct an appropriate deleter in the constructor itself .. or whenever you know what type of data your class is going to hold:
MsgData()
: type_(NULLPTR), data_(nullptr) {}
MsgData(const bool* data)
: type_(BOOL), data_((void*)data), deleter_(&deleter<BOOL>) {}
MsgData(const std::string* data)
: type_(STRING_STD), data_((void*)data), deleter_(&deleter<std::string>) {}
where deleter_ is a member:
std::function<void(void const*)> deleter_;
and deleter is defined as function template:
template<typename T>
void deleter(void const * data) {
delete static_cast<T const *>(data);
}
Once you have these, your destructor would look like this:
~MsgData() {
if (deleter_) {
deleter_(data_);
}
}
Hope that helps.

access the own interface with the scope operator doesnt work?

While playing around with polymorphism and templates i eventually dug up a strange (at least for me) behaviour of the scope operator. When i tried to access a method of a *b*aseclass using the *i*nterface with the scope operator within a *d*erived class, i get a linker error. I can only assume that the scope operator doesnt look into the vtable and tries to run the method directly from the interface, which is actually pure virtual.
Here is the example for that:
struct i
{
virtual void set(char* in, short len) = 0;
virtual char* getStr() = 0;
virtual ~i() {}
};
template <int size = 10>
struct b : public i // this one is like an char-Array
{
char str[size];
void set(char* in, short len) { memcpy(this->getStr(),in,len); }
char* getStr() { return str;}
};
template <int size = 10>
struct d : public b<size> // this one is like an cString
{
void set(char* in) { strcpy(this->getStr(),in); }
};
struct final : public d<4>
{
void test()
{
set("abc"); ///< Works
d<4>::set("abc"); ///< Works
//set("abc",3); ///< Error : no matching function for call to 'final::set(const char [4], int)' (its shadowed by d)
//note: candidates are: void d<size>::set(char*) [with int size = 4]
b<4>::set("abc",3); ///< Works
//i::set("abc",3); ///< Linker Error: (.gnu.linkonce.t._ZN5final4testEv+0x68) : Error : undefined reference to `i::set(char*, short)'
//this->set("abc",3); ///< Error : no matching function for call to 'final::set(const char [4], int)' (its shadowed by d too)
((i*) this)->set("abc",3); ///< Works!
}
};
int main()
{
final f;
f.test();
return 0;
}
The background why i tried this, is to avoid changing the template parameter of every call to a templated base class, when i might change the size of the final class.
So can somebody explain me why this happens with the scope operator?
Funny is that it does work, when casting the "this" pointer to a interface pointer and then using the baseclass's method with that. Is this actually valid and practicable?
BTW: i use GCC 4.1.2
EDIT:
Just to clarify, i know d::set is shadowing b::set .. thats not the problem, i am just asking about the linker error!
When you write Base::symbol in a class context, symbol will
always be resolved statically, with name lookup starting in the
class Base. The reason is simple: that's the way you access
masked members in derived classes. Otherwise, you'd be unable
to chain functions, e.g.:
void
Derived::function()
{
Base::function(); // calls the function in Base before doing anything else.
// ...
}
At the time C++ was being developed, this was felt to be
important, and even today, you'd want to support some way of
doing it.
One idea for working around this:
template <int size=10>
struct d : public b<size>
{
typedef b<size> Base;
// ...
};
Then in final, refer to Base::set.
Oh i finally found the answer to my question by myself:
Polymorphism needs a indirection!
As stated here: Polymorphic objects on the stack?
Thanks for pointing THAT out ;)

Avoiding C++ polymorphism

I recently created my own scripting language. My code structures are heavily based on polymorphism. (I'm not really sure about how is this called. I've got a virtual function and then I derive the class and let the OS decide what to call on runtime):
class Statement
{
virtual void exec() = 0;
};
class PrintStmt : public Statement
{
void exec()
{
std::cout << expression->eval();
};
class AssignStmt : public Statement
{
void exec()
{
vm->bind_var(name, expression->eval())
};
Any ideas how I can rework this so it can be compiled by a pure C compiler?
I know this is general question and there is no single answer, but how would you do this?
Note: I already downloaded the python code as a reference, but it will take time until I figure out how it is working.
Statement would be a struct. In addition to its data members, you will need a function pointer e.g.
struct Statement
{
void(*exec)(Statement* this); // Function pointer
// Other members
};
You would then have different implementations of the functions per statement type and a function for manufacturing objects of the right type e.g.
static void printExec(struct Statement* this)
{
printf("%s", this->whatever);
}
struct Statement* createPrintStatement()
{
struct Statement* statement = calloc(1, sizeof(struct Statement));
statement->exec = printExec;
return statement;
}
And you would invoke it like this:
statement->exec(statement);
The this pointer gives you access to the data members of the particular struct i.e. the instance whose exec method you invoked.
If you have lots of functions, consider using a vtable.
struct VTable
{
void(*exec)(Statement* this); // Function pointer
const char* (*stringValue)(Statement* this); // Function pointer
};
struct Statement
{
struct VTable* vtable;
// Other members
};
You build each a vtable for each kind of object only once
struct VTable printVTable =
{
printExec,
printStringValue
};
You create new objects thus:
struct Statement* createPrintStatement()
{
struct Statement* statement = calloc(1, sizeof(struct Statement));
statement->vtable = &printVTable;
return statement;
}
and invoke the methods thus
statement->vtable->exec(statement);
The vtable method is more or less what C++ does behind the scenes.
The most straightforward way to convert this to C would probably be to use function pointers.
As #DrewNorman said, you will need to understand how vtables work, class layouts etc, and reimplement it (at least partially) in C. The example code below is very limited but gives you a hint of what to expect.
struct Statement {
void (*exec)(struct Statement* s);
};
struct PrintStmt {
struct Statement statement;
char* what;
};
void print_function(struct Statement* s) {
struct PrintStmt* p = (struct PrintStmt*)s;
printf(p->what);
}
// ...
struct PrintStmt p;
p.statement.exec = &print_function;
p.what = "Hello world";
p.statement.exec(p);
There are numerous C projects that use this kind of technique, GObject comes to my mind but it's far from the only one.
(Note: I'm used to C++ not really to C so this may not even be valid C but you get the idea anyway)

Accessing variable outside scope of a callback c++

I have been beating my head around this issue of static versus non-static, callback functions, function pointers, etc... My goal is to access data of a struct outside the scope of my callback interface. I am trying to do this within my class called TextDetect. I thought I was on track when I asked this question: Avoiding a static member function in c++ when using a callback interface from C
However, I still can't access the data without losing scope over the data that I am most interested. At runtime, I get "Access violation reading location ..." I'll point it out below where it fails.
I implemented the answer to my previous question as the following class, shown entirely (Note: vtrInitialize is part of a 3rd party api code int vtrInitialize(const char *inifile, vtrCallback cb, void *calldata);):
class TextDetect {
const char * inifile;
vtrImage *vtrimage;
int framecount;
public:
TextDetect();
~TextDetect();
void vtrCB(vtrTextTrack *track);
static void vtrCB_thunk(vtrTextTrack *track, void *calldata);
int vtrTest(cv::Mat);
bool DrawBox(cv::Mat&);
vtrTextTrack *texttrack;
};
TextDetect::TextDetect() : inifile("vtr.ini")
{
if (vtrInitialize(inifile, vtrCB_thunk, static_cast<void *>(this) ) == -1)
std::cout << "Error: Failure to initialize" << std::endl;
vtrimage = new vtrImage;
}
int TextDetect::vtrTest(cv::Mat imagetest)
{
/*store image data in an image structure*/
}
void TextDetect::vtrCB(vtrTextTrack *track)
{
/*send data to command line from callback */
I've tried copying the data I need a variety of ways and nothing works (this code is a continuation from above):
//texttrack = track;
//texttrack = new vtrTextTrack (*track);
memcpy(texttrack,track,sizeof(*track));
//vtrTextTrackFree(track);
}
void TextDetect::vtrCB_thunk(vtrTextTrack *track, void *calldata)
{
static_cast<TextDetect *>(calldata)->vtrCB(track);
}
This is the member function were I want the data to be used. Texttrack is public member so I might need it outside my class as well (this code is a continuation from above):
bool TextDetect::DrawBox(cv::Mat& tobeboxed)
{
And I get the access violation error at runtime here at this line of code (this code is a continuation from above):
if (texttrack->best->ocrconf > 90)
{
/*do some more stuff*/
}
}
Hopefully I'm understanding this correctly.
It seems to me that the problem is trying to copy those vtrTextTrack structs improperly.
This:
//texttrack = track;
just copies the pointer. If the owner of the struct (probably the caller of the callback function) destroys/deletes the vtrTextTrack, then you're holding on to an invalid pointer.
This one:
memcpy(texttrack,track,sizeof(*track));
will copy all the members of the vtrTextTrack, but will not copy what's being pointed to by it's member pointers (e.g. texttrack->best). Again, if the owner destroys/deletes the track, then you're holding on to invalid pointers.
And since
//texttrack = new vtrTextTrack (*track);
didn't work, I'm guessing that vtrTextTrack doesn't provide a copy constructor.
As for a workaround, first check if your third party library provides a function to copy these structs. If that's not the case (could this be by design?), then you may have to implement one yourself. This might be hard because there might be all kinds of internals that you don't know about. If you don't need the whole vtrTextTrack, I'd say define another struct and store only the information you need. Something along the lines of
SomeType* bestCopier(SomeType* src)
{
SomeType* temp;
/* copy over struct */
return temp;
}
Foo* fooCopier(Foo* src)
{
/*...*/
}
struct myTextTrack
{
public:
myTextTrack(vtrTextTrack* src)
{
//copy over stuff
m_best = bestCopier(src->best);
m_foo = fooCopier(src->foo);
}
private:
/* the members you care about*/
SomeType* m_best;
Foo * m_foo;
}