So I have declared a vector in my class header like this:
...
private:
vector<Instruction> instructions;
...
Then in the .cpp implementation in the constructor, I try to initialize it like this:
instructions = new vector<Instruction>();
Xcode tells me: No viable overloaded '='
I am basically trying to get this class to behave like I would expect in java, where instances of the class retain this vector. Thats why I wanted to dynamically allocate it using new, so as to make sure that it doesn't get lost on the stack or something. Any help would be appreciated with this, thanks so much.
In order to do what you're trying to do the instructions = new vector<Instruction>() line is entirely unnecessary. Simply remove it. The vector will automatically get default-constructed when an instance of your class gets constructed.
An alternative is to make instructions into a pointer, but there doesn't appear to be any reason to do this here.
when you write
vector<Instruction> instructions;
you already have instantiated instructions to whatever memory model the user of your class is using e.g.
class YourClass
{
vector<Instruction> instructions;
};
...
int main()
{
YourClass class1; // stack
std::unique_ptr<YourClass> class2(new YourClass); // heap
...
}
In your class, you declare a std::vector<Instruction>. new vector<Instruction>(); returns you a std::vector<Instruction>*.
operator new returns a pointer, so you have a type mismatch.
The real issue is the fact that you are doing it at all. Do you have a good reason for dynamically allocating that vector? I doubt it, just omit that entirely as it will be allocated along with instances of your type.
You have a member value but you try to initialize it from a vector<Instruction>*. Initialize it from vector<Instruction> or change the declaration to a pointer. If you go down the second route, you need to observe the rule of three.
You might also want to get a decent C++ book from this list.
Also, I think you have a using namespace std; in your header which is bad.
Do not use new in C++ unless you know what you are doing. (Which you do not, currently.)
Instead use automatic objects. You already defined instructions to be an automatic object. You just need to init it as if it were one:
class wrgxl {
public:
wrgxl()
: instructions() // this initializes the vector using its default constructor
{
// nothing needed here
}
...
private:
vector<Instruction> instructions;
...
};
The initialization of instructions in the constructor's initialization list is optional, though, if you only want to call the default constructor anyway. So in this case, this would be enough:
wrgxl()
{
}
If you wanted to dynamically allocate a vector, you would need to make instructions a pointer to a vector. But this rarely ever make sense, since the vector already allocates its data dynamically, but wraps this, so you do not have to deal with the ugly details resulting from this.
One of those details is that, if you have a dynamically allocated object in a class, you will then have to worry about destruction, copy construction, and copy assignment for that class.
As Kerrek already pointed out, you will need to have a good C++ book in order to properly learn C++. Make your pick.
I think you are confusing C++'s with C#'s syntax.
First, unlike in many languages, variables allocated on the stack (such as yours), are initialized by calling the default constructor, so I suspect that what you are doing is unnecessary.
Second, in order to do what you are trying to do, you use the following syntax:
instructions = vector<Instruction>();
however, as I said, this is likely redundant (and wasteful on a non-optimizing compiler as it might call both the constructor and the assignment operator). A much better way to do this is found in sbi's answer.
Third, unlike in C#, the new operator allocates memory on the heap and returns a pointer to the newly allocated data. Your variable instructions is not a pointer, thus the error.
Related
I read other questions trying to figure this out but I didn't find much like what I have in mind. I'm kinda new to C++ and I just don't want to have my C++ code to look like "C with classes", or in other words, if there is a good "C++ way of doing this", that's what I'm looking for, but I'm a bit confused. Well, to the problem.
I have a class, say MyClass. Now, in other class, say MyContainer, I have a vector<MyClass> vec.
Let's say I'm now creating a method that populates a MyClass object with any arbitrary stuff and then pushes it into vec. First question is: should I allocate and push the object like the following? (using vector<MyClass> vec)
MyClass *obj = new MyClass(args);
vec.push_back(*obj);
I am not sure this is right, but by my understanding, this could make me avoid having to manually delete every instance of MyClass I put into vec when the instance of MyContainer is of no use anymore.
What bugs me is that, like I said, this does not seem right anyway, and the other way I can figure out is declaring vector<MyClass*> and writing:
MyClass *obj = new MyClass(args);
vec.push_back(obj);
But this would make me write a method to delete every instance of MyClass I created before, right?
So... What should I use and, if both are actually right, when one is preferrable to the other?
However, if everything is wrong from the start, how can I do this?
Thank yall!
PS: by the way, MyContainer is created in main(). I'm planning to use heap allocation. Should I?
Edit: I can't use C++11.
PS2: This is part of an assignment, but I found it general enough to be of use for anyone, not just me.
You probably shouldn't use new unless you need the object to survive beyond the local scope of the variable.
Just declare it on the stack:
MyClass obj(args);
vec.push_back(obj);
In C++11, you can avoid any risk of extra copies of obj by using:
vec.emplace_back(args);
Whether or not you should allocate on the heap or the stack as suggested by #happydave is highly dependent on the nature of "MyClass", IMO. If you need any kind of polymorphic behavior (i.e. you might have specialized subclasses of MyClass), then you should have a container of pointers.
If you're concerned about needing to delete each of the entries individually, there are two things that might help you:
1 . Use shared_ptr. So your code might look like this:
typedef std::shared_ptr<MyClass> MyClassPtr;
...
vector<MyClassPtr> vec;
vec.push_back(MyClassPtr(new MyClass());
The smart pointer will automatically delete MyClass when there are no more references to it.
2 . If you use bare pointers, you can still delete all the pointers with one line of code using std::for_each. This is described here: Can I call `delete` on a vector of pointers in C++ via for_each <algorithm>?
If you don't need polymorphic behavior and your class is copyable (either you gave it a copy constructor or the default copy is good for your implementation), then you can allocate on the stack.
Is there a way to force a class to be instantiated on the stack or at least prevent it to be global in C++?
I want to prevent global instantiation because the constructor calls C APIs that need previous initialization. AFAIK there is no way to control the construction order of global objects.
Edit: The application targets an embedded device for which dynamic memory allocation is also prohibited. The only possible solution for the user to instanciate the class is either on the stack or through a placement new operator.
Edit2: My class is part of a library which depends on other external libraries (from which come the C APIs). I can't modify those libraries and I can't control the way libraries are initialized in the final application, that's why I am looking for a way to restrict how the class could be used.
Instead of placing somewhat arbitrary restrictions on objects of your class I'd rather make the calls to the C API safe by wrapping them into a class. The constructor of that class would do the initialization and the destructor would release acquired resources.
Then you can require this class as an argument to your class and initialization is always going to work out.
The technique used for the wrapper is called RAII and you can read more about it in this SO question and this wiki page. It originally was meant to combine encapsulate resource initialization and release into objects, but can also be used for a variety of other things.
Half an answer:
To prevent heap allocation (so only allow stack allocation) override operator new and make it private.
void* operator new( size_t size );
EDIT: Others have said just document the limitations, and I kind of agree, nevertheless and just for the hell of it: No Heap allocation, no global allocation, APIs initialised (not quite in the constructor but I would argue still good enough):
class Boogy
{
public:
static Boogy* GetBoogy()
{
// here, we intilialise the APIs before calling
// DoAPIStuffThatRequiresInitialisationFirst()
InitAPIs();
Boogy* ptr = new Boogy();
ptr->DoAPIStuffThatRequiresInitialisationFirst();
return ptr;
}
// a public operator delete, so people can "delete" what we give them
void operator delete( void* ptr )
{
// this function needs to manage marking array objects as allocated
// or not
}
private:
// operator new returns STACK allocated objects.
void* operator new( size_t size )
{
Boogy* ptr = &(m_Memory[0]);
// (this function also needs to manage marking objects as allocated
// or not)
return ptr;
}
void DoAPIStuffThatRequiresInitialisationFirst()
{
// move the stuff that requires initiaisation first
// from the ctor into HERE.
}
// Declare ALL ctors private so no uncontrolled allocation,
// on stack or HEAP, GLOBAL or otherwise,
Boogy(){}
// All Boogys are on the STACK.
static Boogy m_Memory[10];
};
I don't know if I'm proud or ashamed! :-)
You cannot, per se, prevent putting objects as globals. And I would argue you should not try: after all, why cannot build an object that initialize those libraries, instantiate it globally, and then instantiate your object globally ?
So, let me rephrase the question to drill down to its core:
How can I prevent my object from being constructed before some initialization work has been done ?
The response, in general, is: depends.
It all boils down at what the initialization work is, specifically:
is there a way to detect it has not been called yet ?
are there drawbacks to calling the initialization functions several times ?
For example, I can create the following initializer:
class Initializer {
public:
Initializer() { static bool _ = Init(); (void)_; }
protected:
// boilerplate to prevent slicing
Initializer(Initializer&&) = default;
Initializer(Initializer const&) = default;
Initializer& operator=(Initializer) = default;
private:
static bool Init();
}; // class Initializer
The first time this class is instantiated, it calls Init, and afterwards this is ignored (at the cost of a trivial comparison). Now, it's trivial to inherit (privately) from this class to ensure that by the time your constructor's initializer list or body is called the initialization required has been performed.
How should Init be implemented ?
Depends on what's possible and cheaper, either detecting the initialization is done or calling the initialization regardless.
And if the C API is so crappy you cannot actually do either ?
You're toast. Welcome documentation.
You can try using the Singleton pattern
Is there a way to force a class to be instantiated on the stack or at least prevent it to be global in C++?
Not really. You could make constructor private and create said object only using factory method, but nothing would really prevent you from using said method to create global variable.
If global variables were initialized before application enters "main", then you could throw exception from the constructor before "main" sets some flag. However, it is up to implementation to decide when initialize global variables. So, they could be initialized after application enters "main". I.e. that would be relying on undefined behavior, which isn't a good idea.
You could, in theory, attempt to walk the call stack and see from there it is called. However, compiler could inline constructor or several functions, and this will be non-portable, and walking call stack in C++ will be painful.
You could also manually check "this" pointer and attempt to guess where it is located. However, this will be non-portable hack specific to this particular compiler, OS and architecture.
So there is no good solution I can think of.
As a result, the best idea would be to change your program behavior, as others have already suggeste - make a singleton class that initializes your C api in constructor, deinitializes it in destructor, and request this class when necessary via factory method. This will be the most elegant solution to your problem.
Alternatively, you could attempt to document program behavior.
To allocate a class on the stack, you simply say
FooClass foo; // NOTE no parenthesis because it'd be parsed
// as a function declaration. It's a famous gotcha.
To allocate in on the heap, you say
std::unique_ptr<FooClass> foo(new FooClass()); //or
FooClass* foop = new FooClass(); // less safe
Your object will only be global if you declare it at program scope.
More C++ learning questions. I've been using vectors primarily with raw pointers with a degree of success, however, I've been trying to play with using value objects instead. The first issue I'm running into is compile error in general. I get errors when compiling the code below:
class FileReference {
public:
FileReference(const char* path) : path(string(path)) {};
const std::string path;
};
int main(...) {
std::vector<FileReference> files;
// error C2582: 'operator =' function is unavailable in 'FileReference'
files.push_back(FileReference("d:\\blah\\blah\\blah"));
}
Q1: I'm assuming it's because of somehow specifying a const path, and/or not defining an assignment operator - why wouldn't a default operator work? Does defining const on my object here even I'm assuming it's because I defined a const path, Does const even win me anything here?
Q2: Secondly, in a vector of these value objects, are my objects memory-safe? (meaning, will they get automatically deleted for me). I read here that vectors by default get allocated to the heap -- so does that mean I need to "delete" anything.
Q3: Thirdly, to prevent copying of the entire vector, I have to create a parameter that passes the vector as a reference like:
// static
FileReference::Query(const FileReference& reference, std::vector<FileReference>& files) {
// push stuff into the passed in vector
}
What's the standard for returning large objects that I don't want to die when the function dies. Would I benefit from using a shared_ptr here or something like that?
If any member variables are const, then a default assignment operator can't be created; the compiler doesn't know what you would want to happen. You would have to write your own operator overload, and figure out what behaviour you want. (For this reason, const member variables are often less useful than one might first think.)
So long as you're not taking ownership of raw memory or other resources, then there's nothing to clean up. A std::vector always correctly deletes its contained elements when its lifetime ends, so long as they in turn always correctly clean up their own resources. And in your case, your only member variable is a std:string, which also looks after itself. So you're completely safe.
You could use a shared pointer, but unless you do profiling and identify a bottleneck here, I wouldn't worry about it. In particular, you should read about copy elision, which the compiler can do in many circumstances.
Elements in vector must be assignable from section 23.2.4 Class template vector of the C++ standard:
...the stored object shall meet the requirements of Assignable.
Having a const member makes the class unassignable.
As the elements are being stored by value, they will be destructed when the vector is destroyed or when they are removed from the vector. If the elements were raw pointers, then they would have to be explicitly deleted.
I have the following function and a hierarchy of classes such that Multinumber is inherited by Pairs, Rational, and Complex. All of these share functions which are virtual in Multinumber. My problem is the following code. The way it is written right now, the newElement variable goes out of scope when it is added to my setArray which is of type Multinumber**, and I need to figure out some way to allocate memory within this function. Oddly, paramters that are passed into the function, even when printed on the first line, are always empty when I do a cout<<newElement->tostring(); Can anyone tell me what is wrong here?
bool Set::addElement(Multinumber* newElement)
{
bool success = false;
if(isFull())
{
resize();
}
if(!isMember(newElement))
{
setArray[numElements] = newElement;
numElements++;
success = true;
}
return success;
}
EDIT: Yes the poster is correct, this is a homework assignment
To avoid memory troubles replace Multinumber** setArray with std::vector<boost::shared_ptr<Multinumber>> setArray.
In the real world (I understand from your previous question that this is for homework), you wouldn't implement your own set. The standard library provides this functionality (std::set if you want to keep the elements in order; std::unordered_set if you're using C++0x and/or have the appropriate extensions, and prioritize speed over the additional functionality).
You should probably also look into some smart-pointer classes.
That said:
In your code, newElement isn't going out of scope. What happens is that you've been given a pointer to the calling code's data, and the calling code is then letting the pointed-at thing go out of scope.
As I responded to your previous question, you need to use the "virtual clone idiom" to make the copy.
Basically, you want to call new with whatever the type is of the passed-in, pointed-at thing, in such a way that a copy is made. To ensure "that a copy is made", the natural thing to do would be to use the copy constructor with new, that is new whatever(my_existing_whatever_instance). But in C++, constructors cannot be virtual, so we can't actually put the desired type into a new call. Instead, we have to fake it with a member function. Since member functions can be virtual, the correct version clone is looked up in the actual pointed-at thing, which is implemented to call new using its own type, and calling its own copy constructor. The link provides details.
If you need it to grow, make it of type vector<Multinumber*> and use setArray.push_back(newElement).
You need to make sure that the caller keeps the element alive as long as the vector is alive. If not, perhaps add a virtual Clone method to Multinumber that returns a copy (and subclasses implement it). Then, push_back(newElement->Clone()).
I'm having some trouble to find the best way to accomplish what I have in mind due to my inexperience. I have a class where I need to a vector of objects. So my first question will be:
is there any problem having this: vector< AnyType > container* and then on the constructor initialize it with new (and deleting it on the destructor)?
Another question is: if this vector is going to store objects, shouldn't it be more like vector< AnyTipe* > so they could be dynamically created? In that case how would I return an object from a method and how to avoid memory leaks (trying to use only STL)?
Yes, you can do vector<AnyType> *container and new/delete it. Just be careful when you do subscript notation to access its elements; be sure to say (*container)[i], not container[i], or worse, *container[i], which will probably compile and lead to a crash.
When you do a vector<AnyType>, constructors/destructors are called automatically as needed. However, this approach may lead to unwanted object copying if you plan to pass objects around. Although vector<AnyType> lends itself to better syntactic sugar for the most obvious operations, I recommend vector<AnyType*> for non-primitive objects simply because it's more flexible.
is there any problem having this: vector< AnyType > *container and then on the constructor initialize it with new (and deleting it on the destructor)
No there isn't a problem. But based on that, neither is there a need to dynamically allocate the vector.
Simply make the vector a member of the class:
class foo
{
std::vector<AnyType> container;
...
}
The container will be automatically constructed/destructed along with the instance of foo. Since that was your entire description of what you wanted to do, just let the compiler do the work for you.
Don't use new and delete for anything.
Sometimes you have to, but usually you don't, so try to avoid it and see how you get on. It's hard to explain exactly how without a more concrete example, but in particular if you're doing:
SomeType *myobject = new SomeType();
... use myobject for something ...
delete myobject;
return;
Then firstly this code is leak-prone, and secondly it should be replaced with:
SomeType myobject;
... use myobject for something (replacing -> with . etc.) ...
return;
Especially don't create a vector with new - it's almost always wrong because in practice a vector almost always has one well-defined owner. That owner should have a vector variable, not a pointer-to-vector that they have to remember to delete. You wouldn't dynamically allocate an int just to be a loop counter, and you don't dynamically allocate a vector just to hold some values. In C++, all types can behave in many respects like built-in types. The issues are what lifetime you want them to have, and (sometimes) whether it's expensive to pass them by value or otherwise copy them.
shouldn't it be more like vector< AnyTipe* > so they could be dynamically created?
Only if they need to be dynamically created for some other reason, aside from just that you want to organise them in a vector. Until you hit that reason, don't look for one.
In that case how would I return an object from a method and how to avoid memory leaks (trying to use only STL)?
The standard libraries don't really provide the tools to avoid memory leaks in all common cases. If you must manage memory, I promise you that it is less effort to get hold of an implementation of shared_ptr than it is to do it right without one.