3

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.

wfbarksdale
  • 7,498
  • 15
  • 65
  • 88
  • Try `vector* instructions;` – Bala R Oct 16 '11 at 20:17
  • 1
    @BalaR OK, that will make it compile. But why would you do it ? – cnicutar Oct 16 '11 at 20:17
  • What do you mean by "where instances of the class retain this vector" ? – Marc Plano-Lesay Oct 16 '11 at 20:18
  • @cnicutar because `new` returns a pointer to the newly allocated instance and you need a pointer variable to assign it to. – Bala R Oct 16 '11 at 20:18
  • 4
    Please pick up a good book and familiarize yourself with the C++ fundamentals; C++ is not Java. In C++ you should hardly ever say `new`. – Kerrek SB Oct 16 '11 at 20:19
  • @BalaR You're not listening. How is `vector* instructions` better than `vector instructions` ? – cnicutar Oct 16 '11 at 20:19
  • 3
    "*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*" This is utter nonsense. Don't use `new`, please. – ildjarn Oct 16 '11 at 20:19
  • @cnicutar sorry I misunderstood. There are two ways to fix it. One is to change it to a pointer variable and use new just when you need the vector to be allocated (maybe there will be a situation where you wouldn't need the vector at all); the second is of course to skip the line with compilation error and initialize the instance with `vector instructions;` – Bala R Oct 16 '11 at 20:22
  • All of your comments and answers where immensely helpful. Thank you all very much. I now see that I should avoid using dynamic allocation unless I need the object to persist across function calls. – wfbarksdale Oct 16 '11 at 20:40
  • @weezybizzle : Indeed, and even then you should **always** use a smart pointer (`std::shared_ptr<>` or `std::unique_ptr<>`) instead of a raw pointer. – ildjarn Oct 16 '11 at 20:42

7 Answers7

4

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.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • Ummm...you shouldn't so much as "omit" it as you should "change it". He's not even initializing it--he's allocating memory on the heap. Completely contrary to what he likely intended. – riwalk Oct 16 '11 at 20:21
  • @Stargazer712: No, omit *is* what I mean. – NPE Oct 16 '11 at 20:22
  • 2
    @aix, then I disagree with your answer. "Omit" implies that his code is merely unnecessary--an extra step in an otherwise correct program. His code is flat out wrong. – riwalk Oct 16 '11 at 20:24
  • 1
    @Stargazer712: He wants a vector inside an object. Omitting the faulty assignment will still leave him with a default-initialized vector (which is what he wanted). You don't really want to argue about the semantics of the verb 'omit', do you? I'm not a native speaker but both my understanding and a dictionary tell me that omit means to leave something out. – pezcode Oct 16 '11 at 20:40
  • @Stargazer712: This is not how I meant it to read. I've edited the answer in an attempt to avoid the ambiguity. – NPE Oct 16 '11 at 20:42
3

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
...
}
MSalters
  • 173,980
  • 10
  • 155
  • 350
AndersK
  • 35,813
  • 6
  • 60
  • 86
  • This answer actually addressed the exact piece of information that I needed to understand this. Thanks very much @Anders – wfbarksdale Oct 17 '11 at 05:58
2

In your class, you declare a std::vector<Instruction>. new vector<Instruction>(); returns you a std::vector<Instruction>*.

Marc Plano-Lesay
  • 6,808
  • 10
  • 44
  • 75
  • ahhh, darn these pointers! thanks so much for help, I'll accept in 12 minutes when it lets me. Is it the case that any allocation using `new` will return a pointer to an object? – wfbarksdale Oct 16 '11 at 20:19
  • 3
    @weezybizzle: Yes, it is. And you rarely ever want them. – sbi Oct 16 '11 at 20:20
2

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.

Ed S.
  • 122,712
  • 22
  • 185
  • 265
1

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.

Community
  • 1
  • 1
pmr
  • 58,701
  • 10
  • 113
  • 156
  • why is `using namespace std;` bad? – wfbarksdale Oct 16 '11 at 20:40
  • 2
    @weezybizzle Headers are included by other files. Those files then get the using directive implicitly and it causes havoc as soon as your try to define something with a name like `count` as it clashes with names in the namespace `std`. – pmr Oct 16 '11 at 20:42
  • `+1` from me for bashing `using namespace std`. That's a bad habit, which [might bite you one day](http://stackoverflow.com/questions/2879555/c-stl-how-to-write-wrappers-for-cout-cerr-cin-and-endl/2880136#2880136). – sbi Oct 16 '11 at 21:05
1

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.

Community
  • 1
  • 1
sbi
  • 219,715
  • 46
  • 258
  • 445
  • You don't even need to initialize it. It's, as you said, automatic. – Marc Plano-Lesay Oct 16 '11 at 20:26
  • I like this one. Teaches good habits (and includes an implicit idea of how do do this even when not dealing with a default constructor). – riwalk Oct 16 '11 at 20:26
  • @Kernald: Yeah, I meant to add that while I wrote the ctor, but then forgot. Thanks for reminding me! – sbi Oct 16 '11 at 20:30
  • 1
    Gosh, how I hate those anonymous downvoting bastards! ___What's wrong with this, dammit?!___ (And if you did this out of jealousy: If your answer here has at least one upvote, it's likely that I upvoted it, too.) – sbi Oct 16 '11 at 21:07
0

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.

riwalk
  • 14,033
  • 6
  • 51
  • 68
  • Actually, it would be better to initialize it in the initialization list, although it's optional there, too, when you want the def ctor called. – sbi Oct 16 '11 at 21:08
  • @sbi, you're absolutely right, and I edited mine after you posted yours to make reference to that. – riwalk Oct 16 '11 at 21:38