how to pin_ptr a whole object?

  • Thread starter Thread starter Tao.Young
  • Start date Start date
T

Tao.Young

when i doing this:

pin_ptr<A> pA = gcnew A; // assume A is a ref class

i'll get many compiler errors.
does anyone know how to do it correctly?
Thanks in advance.
 
well, for one thing, your constructor call does not have round braces to it.
it should be A().

also, A pinning pointer can point to a reference handle, value type or boxed
type handle, member of a managed type or to an element of a managed array.
It cannot point to a reference type.

this compiles:
Splash ^ sp = gcnew Splash();
pin_ptr<int> pI = &sp->myInt;

while this doesn't:
pin_ptr<Splash> pS = gcnew Splash();

kind regards,
Bruno.
 
In addition to Bruno's explanations, you should also know that having a
pinning pointer refering into your object actually pins the whole object.
 
Bruno van Dooren said:
well, for one thing, your constructor call does not have round braces to
it. it should be A().
Why? The new-initializer is and has always been optional in
new expressions. This is no different in C++/CLI or even for
gcnew expressions.

In C++ omitting the parens is IMHO the preferred way
as these can lead to confusions with function types.

-hg
 
but that only works if is there is an appropriate default constructor.
else you will get compiler error C2512: no appropriate default constructor.

using round braces will work in all situations, and it also shows that you
explicitly want to use a specific constructor.

kind regards,
Bruno.
 
Bruno said:
but that only works if is there is an appropriate default constructor.
else you will get compiler error C2512: no appropriate default constructor.

using round braces will work in all situations, and it also shows that you
explicitly want to use a specific constructor.

Are you sure? If there's no default constructor, gcnew T(); will fail
the exact same way as gcnew T;. In C++ we never had to use the () syntax
to call the default constructor. It's C# and Java syntax.

On the contrary, I'm pretty sure it's a mistake to use the () syntax to
call the default constructor. The compiler will treat you code as a
function declaration:

class C
{
public:
C();
};

void Test()
{
C test();
// this is not the default constructor, but a function declaration!
}

With new and gcnew you are allowed to use () with the default
constructor, but I feel it's a bad practice to do so. It's definitely
not an error to skip the () with the default constructor.

Tom
 
i think it is a matter of taste really. i am used to using round braces
because to me, it means call constructor.

always using round braces works if there is a default constructor, and if
there isn't.
whereas not using them will work with default constructors, but not with
other constructors.

that's why i prefer always to use braces. but it's not an error to either do
it or not do it.

kind regards,
BRuno.
 
Bruno said:
always using round braces works if there is a default constructor, and if
there isn't.
whereas not using them will work with default constructors, but not with
other constructors.

That logic makes sense. It's really a style issue, a matter of personal
preference.

With the stack syntax, however, it's an error to use the extra ():

MyClass class();

This doesn't create a new instance called "class", but rather declares a
function named "class" that returns MyClass and takes no argument.
That's why many C++ programmers don't like the idea of using the ()
syntax with default constructors. But with "new" or "gcnew", it's really
optional.

Tom
 
Tamas said:
That logic makes sense. It's really a style issue, a matter of personal
preference.

That's not entirely true. You're all correct that putting empty parenthesis
after the type in local declaration can be confused with a function
prototype, the new expression is very different.

In general, if the () are included in a new expression (i.e. "new T()"),
then the item is value intialized (basically the compiler zeros out the
memory first). If the parenthesis are omitted, and the type is a non-POD,
item is default initialized. If the item is POD type, then state of the
program is indeterminate (and in some cases the program is ill-formed).

So, there's a performance cost to including the () in a new expression, but
it makes the program more likely to be correct.

More info is in the C++ Standard 5.3.4/15.

For gcnew, the CLR always zeros out memory before any constructor runs... so
the difference between default initialized and value initialized isn't any
different.
 
Ok, that's the answer I exactly want to know.
Thanks, Marcus and Bruno!

ps: as to the parenthesis problem, i really don't whether it will cause
problems.
C++/CLI is some kind hard for me to understand now. :-)
 
Back
Top