I am trying to use an open source class whose .h file starts with:
template <class DT>
class FFTReal
{
public:
enum { MAX_BIT_DEPTH = 30 };
typedef DT DataType;
explicit FFTReal (long length);
...
my first creating a pointer to the class in my private section of my class:
ffft::FFTReal<double> *m_fft_object;
And then, within an initialization function, create it with
m_fft_object = new fft_object((long)(FFTWindowSize));
It is in this last line that I get the error "Error:expected a type".
I have done some searches for the error but nothing seems to match my particular problem.
Thanks
Presumably this is because fft_object is not a type. You probably meant this:
m_fft_object = new ffft::FFTReal<double>(static_cast<long>(FFTWindowSize));
I also corrected the C-style cast for you.
As noted in the comments, you should avoid using raw pointers to store object data unless you have a very good reason. Consider using a smart pointer (std::unique_ptr<ffft::FFTReal<double>>) if the data should be nullable, otherwise you can simply store an object instance as a value (ffft::FFTReal<double>). Either option will make memory leaks extremely unlikely, whereas when using new and raw pointers you have to be extremely careful to delete the allocated object when you are done with it.
Related
I am not sure if this is a syntax issue but I have tried messing with the declarations and can't seem to shake the error. Here are my private member variables in the header file.
class PrimeGenerator
{
private:
unique_ptr<bool[]> sequence;
int length;
These declarations drew a BAD_ALLOCATION error. Is my syntax incorrect? How do I declare the members of the unique_ptr array?
sequence[0] = 0;
sequence[1] = 0;
sequence[2] = 1;
It appears that in your code unique_ptr<bool[]> sequence; does not have any value to point into.
unique_ptr<bool[]> sequence{new bool[3]};
You can try with the above code. Also as mentioned, a smart pointer is a class that wraps a 'raw' (or 'bare') C++ pointer, to manage the lifetime of the object being pointed to.
With raw pointers, the programmer has to explicitly destroy the object when it is no longer useful. A smart pointer by comparison defines a policy as to when the object is destroyed. You still have to create the object, but you no longer have to worry about destroying it.
I'm trying to wrap my head around C++. I'm going to just give you tiny pieces to help illustrate the idea without making things to convoluted. Btw, im only implementing these methods, i cannot change the setup or parameters.
I have a class for a dynamic array data structure that holds objects called stocks:
typedef class Stock ArrayType;
class DynamicArray {
ArrayType** items;
int numberOfElements;
...
}
Here's its constructor. I'm supposed to allocate the array and add one item, then set the number of elements.
DynamicArray::DynamicArray(ArrayType* const item){
Stock *items = NULL; // ... i guess? pointers to pointers confuse me
// now im guessing i need to create a actual stock array and point the above pointer to it
items = new Stock[1]; // ERROR: incomplete type is not allowed? I've tried several things, and cant get rid of the red squiggles
this->numberOfElements = 1;
}
Okay, there are a few problems. Off the bat, you have to include Stock first. The compiler needs the full definition of Stock before it can compile DynamicArray, because of memory allocation by my guess.
Secondly, you want the items member-value to contain the reference to the array created in the constructor. So instead of defining Stock *items[1] in the constructor, assign the value of the new statement directly to this->items; you can ommit this-> as long as you don't define a variable with the same name in whatever function you're working on.
Finally, you're allocating an array of pointers, so you use this syntax: new ArrayType*[1]
Additionally, just as a coding-practices point, you shouldn't mix the use of typedefs and their original types in the same source. So I'd recommend you use ArrayType throughout or not at all.
I'm packing some classes into ptr_map with any typed value.
class EventManager
{
ptr_map<string, any> mSomeMap;
public:
typedef signals2::signal<void (int someSignature)> KeyEvent;
EventManager()
{
mSomeMap["KeyPressed"] = new any(new KeyEvent());
}
};
Now I want to restore my signal object from any. Here is a special function for this:
template<typename EventType>
EventType *get(const string &signalName)
{
try {
return any_cast<EventType*>(mSomeMap[signalName]);
} catch(bad_any_cast &e){}
}
As you could remember, the boost's signals are noncopyable so I can store only pointers and my function should return pointers too.
Now sample usage:
evManager.get<EventManager::KeyEvent>("KeyPressed");
Here I get segfault. I checked the types of each objects in the get function:
typeid(EventType).name()
→ N5boost8signals26signalIFvRN2sf5Event8KeyEventEENS0_19optional_last_valueIvEEiSt4lessIiENS_8functionIS6_EENSB_IFvRKNS0_10connectionES5_EEENS0_5mutexEEE
mSignalAssociation[signalName].type().name()
→ N10__cxxabiv119__pointer_type_infoE
What's wrong is there? The segfault at line with casting. Any object should consist of inserted type or not? Why it doesn't want to cast.
ptr_map<string, any> mSomeMap;
...
mSomeMap["KeyPressed"] = new any(new KeyEvent());
Do you realize what happens here? First, you create a KeyEvent object dynamically which results in a pointer. Then this pointer is wrapped into an any-object which is also dynamically created which also returns a pointer which is then again wrapped in another any object implicitly by the assignment.
Also, for extracting the right value from an any object you need to know the exact type. So, for example, if you pack a Derived-pointer into an any object, you won't be able to access it via an any_cast<Base*> because Base* and Derived* are different types in terms of the std::type_info objects boost::any uses to keep track of types. boost::any just doesn't know how to convert the packed Derived-pointer to your Base-pointer.
Is there a special reason why you wrap so many things in any-objects including pointers to any-objects? Wouldn't it make sense to use something like a ptr_map<KeyType,BaseType>? You know that if you pack a pointer into an any object that you still need to delete the pointees yourself, right? The any-object is not going to do this for you.
i have a "data provider" which stores its output in a struct
of a certain type, for instance
struct DATA_TYPE1{
std::string data_string;
};
then this struct has to be casted into a general datatype,
i thought about void * or char *, because the "intermediate"
object that copies and stores it in its binary tree should
be able to store many different types of such struct data.
struct BINARY_TREE_ENTRY{
void * DATA;
struct BINARY_TREE_ENTRY * next;
};
this void * is then later taken by another object
that casts the void * back into the (struct DATA_TYPE1 *)
to get the original data. so the sender and the receiver
know about the datatype DATA_TYPE1 but not the copying
object inbetween.
but how can the intermidiate object deep copy the contents of
the different structs, when it doesn't know the datatype,
only void * and it has no method to copy the real contents;
dynamic_cast doesn't work for void *;
the "intermediate" object should do something like:
void store_data(void * CASTED_DATA_STRUCT){
void * DATA_COPY = create_a_deepcopy_of(CASTED_DATA_STRUCT);
push_into_bintree(DATA_COPY);
}
a simple solution would be that the sending object doesn't
delete the sent data struct, til the receiving object got it,
but the sending objects are dynamically created and deleted,
before the receiver got the data from the intermediate object,
for asynchronous communication, therefore i want to copy
it.
instead of converting it to void * i also tried converting
to a superclass pointer of which the intermediate copying
object knows about, and which is inherited by all the different
datatypes of the structs:
struct DATA_BASE_OBJECT{
public:
DATA_BASE_OBJECT(){}
DATA_BASE_OBJECT(DATA_BASE_OBJECT * old_ptr){
std::cout << "this should be automatically overridden!" << std::endl;
}
virtual ~DATA_BASE_OBJECT(){}
};
struct DATA_TYPE1 : public DATA_BASE_OBJECT {
public:
string str;
DATA_TYPE1(){}
~DATA_TYPE1(){}
DATA_TYPE1(DATA_TYPE1 * old_ptr){
str = old_ptr->str;
}
};
and the corresponding binary tree entry would then be:
struct BINARY_TREE_ENTRY{
struct DATA_BASE_OBJECT * DATA;
struct BINARY_TREE_ENTRY * next;
};
and to then copy the unknown datatype, i tried in the class
that just gets the unknown datatype as a struct DATA_BASE_OBJECT *
(before it was the void *):
void * copy_data(DATA_BASE_OBJECT * data_that_i_get_in_the_sub_struct){
struct DATA_BASE_OBJECT * copy_sub = new DATA_BASE_OBJECT(data_that_i_get_in_the_sub_struct);
push_into_bintree(copy_sub);
}
i then added a copy constructor to the DATA_BASE_OBJECT, but if
the struct DATA_TYPE1 is first casted to a DATA_BASE_OBJECT and then
copied, the included sub object DATA_TYPE1 is not also copied.
i then thought what about finding out the size of the actual object
to copy and then just memcopy it, but the bytes are not stored in
one row and how do i find out the real size in memory of the
struct DATA_TYPE1 which holds a std::string?
Which other c++ methods are available to deepcopy an unknown datatype
(and to maybe get the datatype information somehow else during
runtime)?
If you have a void * there is no way of extracting any type information from it. That is why void * are very, very rarely used in C++ programs (I honestly cannot remember the last time I used one) - your approach here is completely mistaken. If you want generic containers where the type is known at compile time, use templates. If you want containers where the type varies at run-time, derive from a base class and use containers of base class pointers. And don't write your own containers (except possibly as learning exercises ) - C++ has a perfectly good binary tree implemented as std::set and std::map.
And lastly, don't use ALL CAPS for names of C++ types.
Void pointers are not a good solution here because they do not guarantee type-safety at compiletime.
I suggest using templates. This will allow you to still deal with different datatypes using the same class/functions, and will also guarantee typesafety much better than void pointers.
Edit: To further clarify why void pointers even exist: void pointers were used for this kind of thing in C. However while you can still use them in C++, it is usually discouraged because there are better solutions.
Also, you mention deepcopying. All types to be used with the database should either have to implement deepCopy function (this is an OOP-style approach), or you could simply remember to overload the assignment operator for all types you use with your DATA_BASE :)
but how can the intermidiate object deep copy the contents of the different structs, when it doesn't know the datatype, only void * and it has no method to copy the real contents; dynamic_cast doesn't work for void *;
You simply can't do that. A void* block representing certain data is bound to contain multiple pointers (std::string allocates memory dynamically, for example). And you won't know where exactly they are stored, so there will be no way to deep copy data without causing a mess somewhere.
dynamic_cast doesn't work for void *;
You could try to cast void* into some base type, then dynamic_cast into whatever you want. However, I can't guarantee that it will be safe to use that with object created by multiple inheritance, for example. It will be safer to use some abstract class for exchanging data, instead of void* pointers.
Which other c++ methods are available to deepcopy an unknown datatype (and to maybe get the datatype information somehow else during runtime)
What you're looking at here is serialization: The ability to place various objects in a binary stream, move the stream around - and maybe store it, then get a copy of the original contents back out of the stream.
You can implement this yourself, or you can base your implementation on existing libraries.
One option I have used is boost::serialization. You basically have to implement either a serialize method in all your class hierarchy, or a save and a load method in all your class hierarchy.
The code is pretty straightforward. See here for the tutorial.
thanks for the quick answers.
i'm somehow too lazy to rewrite the code in the future each time
in every class when a new datatype is added.
for me now i could do it with templates for each datatype that is used,
but i really wonder from a code development point of view if there
isn't a simpler thing in c++. you are right that i come from c and
i will slowly behave myself when programming in c++.
i tried this approach with inheritance of a base class, which
is already a restriction for coding, because every new datatype
has to be coded to inherite the base struct, but this doesn't work,
because only calling the copy contructor of the base struct, which is
the only thing the "copy-object" knows (because it doesn't know anything
about the derived struct datetypes), can do, doesn't work.
the copy contructor of the derived struct is not called, or am i doing
something wrong here? i tried it with the assignment operator, but
it doesn't do a copy and as soon as the original data is deleted,
it is a dangling pointer i guess.
At the moment it works like this
the "sending object" creates a struct DATA_TYPE1 * with new DATA_TYPE1 ...
and fills it with data
and casts it to void *
and tells the "copy-object" about this pointer
then the "sending object" is deleted, the contents of the void * is still alive
the "copy-object" stores just the void *
the "receiving object" gets this void * at a later time
and casts it back to the struct DATA_TYPE1 * and uses its data
and finally deletes the data
so no copying is done here just handing over the pointer to
the original data from one object to the other.
thanks for the advice about serialisation i thought about that,
but at the moment i want to turture myself with pure c++ to
solve this problem.
I'd have to say I'm no expert on using the STL. Here's my problem, I have a class Called LdapClientManager which maintains a number of LDAP clients that are managed by ID. The container holding the LdapClients is declared as a member variable i.e.
typedef std::map<int, LdapClient *> LdapClientMap;
LdapClientMap _ldapClientMap;
The following function fails to compile with the error:
LdapClient * LdapClientManager::getLdapClient(unsigned int templateID)
{
// Do we have an LdapClient
LdapClientMap::const_iterator it = _ldapClientMap.find(templateID);
if (it == std::map::end) {
// no existing client, lets create it
LdapClient * ldapClient = new LdapClient();
if (ldapClient == NULL) {
// TODO: handle out of memory condition
}
_ldapClientMap[templateID] = ldapClient;
return ldapClient;
}
return it->second;
}
Unfortunately I get the following error at compile time, what does it mean. I haven't found a solution in google as yet.
LdapClientManager.cc: In member function LdapClient*
LdapClientManager::getLdapClient(unsigned int)':
LdapClientManager.cc:33:template class std::map' used without template parameters
Replace std::map::end with _ldapClientMap.end().
Also, new never returns 0, it throws an exception if the allocation fails.
Note that the program can be made much shorter.
LdapClient * LdapClientManager::getLdapClient(unsigned int templateID)
{
LdapClient *& value = _ldapClientMap[templateID];
if (value == 0)
value = new LdapClient();
return value;
}
It means exactly what it says it means. std::map is a class template. It is not a class in and of itself. It needs template parameters, like you used when you defined the LdapClientMap type. Later, you say std::map::end, and the compiler says that needs parameters, too.
But you probably meant _ldapClientMap.end(). Each map has its own end; end is not a static function, so you need to call it on an instance. If it were static, you would have needed to provide template parameters, just like when you defined the type: std::map<int, LdapClient*>::end.
std::map::end() is a member function of the container instance and not a universal value, so you'll need to check the result of std::map::find() against _ldapClientMap.end().
Another couple of suggestions to improve the code:
Standard C++ containers have value semantics (they want to store the actual object and not a pointer to the object). If you really need to store pointers to LdapClients instead of the LdapClient objects themselves, I would strongly recommend wrapping them in an appropriate smart pointer like boost::shared_ptr (not std::auto_ptr, which will not work). This way, the automatic memory management of the std::map will still work and destroy the objects as intended. If you don't want to use a smart pointer or put the actual LdapClient object into the container, you will have to manually manage the objects' lifetime and call delete when appropriate to prevent memory leaks. My preference would be to change the type of the map to std::map unless the LdapClient objects are polymorphic.
Unless you are using a very out of date compiler, checking the result of regular new() against 0 or NULL will not yield any new insights as new throws a std::bad_alloc these days when it can't allocated memory for whatever reason.
Instead of using _ldapClientMap[x] = y; to insert a new element, I would use _ldapClientMap.insert(LdapClientMap::value_type(x,y)) as the latter will not overwrite an existing value for key x (which the former will do) and will return 'false' in case the key already exists in the map. That is of course if that is your intention.
LdapClientMap _ldapClientMap;
You should avoid using names with a leading underscore. Technically it is undefined behavior, even if the compiler allows it because by using it you conflict with current or future reserved names.