-
September 11th, 2011, 08:22 AM
#1
How do you declare a vector in VS C++2008/managed?
Hello. This is not homework. I am just studying different tools for my job as a programmer, trying to decide which will be best for me to use at work. One of the tools is Visual Studio (which I am finding out I do not care for, Code::Blocks is better, but in case I must use all managed code at work, I want to know how to do it)
I do not wish to mix managed and unmanaged code in this program.
What is the proper way to declare a vector using only managed code?
Here is what I have (the relevant parts anyway)
Code:
#pragma once
#include <math.h>
#include <vector>
namespace Calculator {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace std; //for vector
//lots of code in between...
private: System::Void button21_Click(System::Object^ sender, System::EventArgs^ e) {
array< String^ >^ sentence = gcnew array< String^ >(ARRAY_SIZE);
//I included the array because it works, and I assume the vector declaration should be similar?
vector<String^> word = gcnew vector<String^>; //what is missing on this line?
//this gives me: error C2726: 'gcnew' may only be used to create an object with managed type
String^ x = "Hello! ";
word.push_back(x);
//error C2440: 'initializing' : cannot convert from 'std::vector<_Ty> *' to 'std::vector<_Ty>'
//I assume that managed code would have a -> instead of the dot member operator, wouldn't it?
}
}
Since I posted this before, in a different section (sorry!), I found a solution that seems to work, though I still don't know if this is the 'right' way to do it.
Code:
System::Collections::Generic::List<String^> word;
word.Add("Hello!");
word.Add("Goodbye!");
-
September 11th, 2011, 05:57 PM
#2
Re: How do you declare a vector in VS C++2008/managed?
As you probably have seen in the threads I linked you to in the other thread over there in the VC++ section, it's not really advisable to use the STL/CLR containers without really good reasons. In particular I recommend against using them as a mere convenience feature for native C++ developers who add C++/CLI to their repertoire.
Yes, the List<T> you used in your second code snippet is the .NET container of choice for this purpose. (Actually, when I was new to C++/CLI and looking for an equivalent to std::vector, I failed to consider it at all because its name reminded me to std::list which, as we know, is something completely different. I ended up not only using cliext::vector but also other STL/CLR containers which got me into considerable trouble, and that's what http://www.codeguru.com/forum/showthread.php?t=503117 is about. I only did that in that single program ever... )
However, note that what you've created in your snippet is a thing called implicitly dereferenced variable. (That's because you used that syntax for a reference type. If you'd have used it for a value type like int it wold actually be an ordinary local variable like it would be in native C++.) Implicitly dereferenced variables pretty much have the look and feel of ordinary local variables, yet they still represent an instance of a reference type behind the scenes. In particular, the instance gets implicitly default-constructed (unless you provide construction parameters) when the declaration is reached during execution. Also, and that's what I like most about them, they implicitly get deleted (in .NET speak: disposed) when the variable goes out of scope.
I really like them and use them every now and then in my code, but I try to avoid them in code I intend to post here on the forum. That's because AFAIK they're a speciality of C++/CLI (the only comparable construct I kow of is the using statement in C#, but that looks different) and tend to obscure the reference type semantics going on behind the scenes. For these reasons I'm afraid they can be confusing for programmers new to C++/CLI, perhaps especially when they already know another .NET language where AFAIK they always need to explicitly create reference type instances using the new operator (C# in this case) or something equivalent.
So, for comparison, your snippet expressed in the "usual" reference type syntax looks like this:
Code:
System::Collections::Generic::List<String^> ^word = gcnew System::Collections::Generic::List<String^>;
word->Add("Hello!");
word->Add("Goodbye!");
I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.
This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|