473,386 Members | 2,078 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Beta 2: Automatic Dispose inaction?

Hello,

The following doesn't compile due to absence of the copy constructor in class FileStream:

FileInfo ^ fi = ...;
FileStream fs = fi->OpenRead();

The compiler is Beta 2. Is this supported? Planned to be supported?
Nov 17 '05 #1
11 1280
Alexei wrote:
Hello,

The following doesn't compile due to absence of the copy constructor
in class FileStream:

FileInfo ^ fi = ...;
FileStream fs = fi->OpenRead();


FileStream^ fs = fi->OpenRead();

-cd
Nov 17 '05 #2
Carl Daniel [VC++ MVP] wrote:
Alexei wrote:
Hello,

The following doesn't compile due to absence of the copy constructor
in class FileStream:

FileInfo ^ fi = ...;
FileStream fs = fi->OpenRead();


FileStream^ fs = fi->OpenRead();


Don't answer just to answer. Look here: http://blogs.msdn.com/arich/ (DF
pattern).
Nov 17 '05 #3

"Alexei Zakharov" <al********@at.gmail.com> wrote in message
news:uu**************@TK2MSFTNGP15.phx.gbl...
Carl Daniel [VC++ MVP] wrote:
Alexei wrote:
Hello,

The following doesn't compile due to absence of the copy constructor
in class FileStream:

FileInfo ^ fi = ...;
FileStream fs = fi->OpenRead();


FileStream^ fs = fi->OpenRead();


Don't answer just to answer. Look here: http://blogs.msdn.com/arich/ (DF
pattern).


This pattern is for C++/CLI implemented classes only, the FCL are written in
C# and their classes can't be "stack allocated". So, what you should do is,
allocate the object on the heap and manually dispose.

Willy.

Nov 17 '05 #4
"Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message
news:uK**************@TK2MSFTNGP14.phx.gbl
This pattern is for C++/CLI implemented classes only, the FCL are
written in C# and their classes can't be "stack allocated". So, what
you should do is, allocate the object on the heap and manually
dispose.


It doesn't seem plausible since I can write:
FileStream fs("myfile", FileMode::Create);
And it will work.
Nov 17 '05 #5

"Alexei" <al*****@at.gmail.com> wrote in message
news:uI*************@tk2msftngp13.phx.gbl...
"Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message
news:uK**************@TK2MSFTNGP14.phx.gbl
This pattern is for C++/CLI implemented classes only, the FCL are
written in C# and their classes can't be "stack allocated". So, what
you should do is, allocate the object on the heap and manually
dispose.


It doesn't seem plausible since I can write:
FileStream fs("myfile", FileMode::Create);
And it will work.


Sorry for not being more explicit. The FileInfo->OpenRead returns a
FileStream object reference (heap allocated), you can't assign it to a stack
allocated variable.
So what you could do is...

FileInfo fi(".....");
FileStream ^fs = fi.OpenRead();

Willy.

Nov 17 '05 #6
Willy Denoyette [MVP] wrote:
"Alexei" <al*****@at.gmail.com> wrote in message
news:uI*************@tk2msftngp13.phx.gbl...
"Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message
news:uK**************@TK2MSFTNGP14.phx.gbl
This pattern is for C++/CLI implemented classes only, the FCL are
written in C# and their classes can't be "stack allocated". So, what
you should do is, allocate the object on the heap and manually
dispose.
It doesn't seem plausible since I can write:
FileStream fs("myfile", FileMode::Create);
And it will work.


Sorry for not being more explicit. The FileInfo->OpenRead returns a
FileStream object reference (heap allocated), you can't assign it to
a stack allocated variable.


There is no such thing as stack allocation for ref classes. So the whole
your argument is moot.

{
FileStream fs(...);
}

is equivalent to:

{
FileStream ^ fs = gcnew FileStream(...);
try {
} finally {
delete fs;
}
}

See, the object is still on GC heap. You can't place it on stack. What you
have is just a language construct that sort of looks like a stack-based
placement.

Now, does it matter if the object is created with gcnew or by calling a
function? No, IMO. The same code I can rewrite with using fi.OpenRead():

{
FileStream ^ fs = fi.OpenRead();
try {
} finally {
delete fs;
}
}

What leads me to simply:

FileStream fs(fi.OpenRead());

I can't understand the point of having copy-constructors for ref classes.
..NET object model is fundamentally different from C++ object model. There
is no copy-construction per se in .NET (besides trivial bitwise copy for
value classes). Objects are passed around by reference not by value as in
C++, so copying is not needed. I don't see the reason for C++/CLI to
introduce an idiom that can't have any relevence for .NET programming.
So what you could do is...

FileInfo fi(".....");
FileStream ^fs = fi.OpenRead();

Nov 17 '05 #7
> There is no such thing as stack allocation for ref classes.

The point is "stack semantics", not "stack allocation". The memory for
the object is indeed allocated from GC heap, but it is (mostly)
irrelevant here.

Nov 17 '05 #8
Who's talking about stack allocated reference classes, I said "assign it to
a stack allocated variable" right?
I know ref. classes aren't stack allocated, they have stack semantics.

For the compiler there's a difference between:
FileStream fs = fi->OpenRead();
and
FileStream fs(...);
The first is an assignment of a "stack allocated variable", with stack
semantics, to a value with "reference" semantics (of type FileStream),
returned by a (C#) function call. This is something that the current C++
compiler can't handled, why he's insisting on a copy constructor is beyond
me, ref class can't have copy constructors.
The latter is a constructor call, that upon return (note: nothing is
returned from the constructor!!!), initializes a stack allocated variable
with stack semantics. This initialization is completely handled by the C++
compiler.

Herewith a simple sample that illustrates the issue:

// C#
public class Tester
{
public Test GetTest()
{
Test t = new Test();
return t;
}
}

public class Test
{...
}
}

// C++
Tester t;
Test tt = t.GetTest();

Willy.

"Alexei" <al*****@at.gmail.com> wrote in message
news:eo****************@TK2MSFTNGP14.phx.gbl...
Willy Denoyette [MVP] wrote:
"Alexei" <al*****@at.gmail.com> wrote in message
news:uI*************@tk2msftngp13.phx.gbl...
"Willy Denoyette [MVP]" <wi*************@telenet.be> wrote in message
news:uK**************@TK2MSFTNGP14.phx.gbl
This pattern is for C++/CLI implemented classes only, the FCL are
written in C# and their classes can't be "stack allocated". So, what
you should do is, allocate the object on the heap and manually
dispose.

It doesn't seem plausible since I can write:
FileStream fs("myfile", FileMode::Create);
And it will work.


Sorry for not being more explicit. The FileInfo->OpenRead returns a
FileStream object reference (heap allocated), you can't assign it to
a stack allocated variable.


There is no such thing as stack allocation for ref classes. So the whole
your argument is moot.

{
FileStream fs(...);
}

is equivalent to:

{
FileStream ^ fs = gcnew FileStream(...);
try {
} finally {
delete fs;
}
}

See, the object is still on GC heap. You can't place it on stack. What
you have is just a language construct that sort of looks like a
stack-based placement.

Now, does it matter if the object is created with gcnew or by calling a
function? No, IMO. The same code I can rewrite with using fi.OpenRead():

{
FileStream ^ fs = fi.OpenRead();
try {
} finally {
delete fs;
}
}

What leads me to simply:

FileStream fs(fi.OpenRead());

I can't understand the point of having copy-constructors for ref classes.
.NET object model is fundamentally different from C++ object model. There
is no copy-construction per se in .NET (besides trivial bitwise copy for
value classes). Objects are passed around by reference not by value as in
C++, so copying is not needed. I don't see the reason for C++/CLI to
introduce an idiom that can't have any relevence for .NET programming.
So what you could do is...

FileInfo fi(".....");
FileStream ^fs = fi.OpenRead();


Nov 17 '05 #9
Alexei wrote:
Now, does it matter if the object is created with gcnew or by calling a
function? No, IMO. The same code I can rewrite with using fi.OpenRead():

{
FileStream ^ fs = fi.OpenRead();
try {
} finally {
delete fs;
}
}
Something like this would be nice, but it can't be done the way you're
trying to do it.
What leads me to simply:

FileStream fs(fi.OpenRead());
I think the code above would expand to

FileStream^ fs = gcnew FileStream(fi.OpenRead());
[...]

and there is no such copy constructor in FileStream (and even if there
was one, you wouldn't want to make a copy in this case).
I can't understand the point of having copy-constructors for ref classes.


There is such a thing as copy c'tor and assignment operator in C++/CLI.
Because what if you want to make a copy? You could always define a
static member (class method) name CopyMe, but C++/CLI was designed to be
as conforming with C++ as possible. The stack syntax with ref classes
has to work like stack objects in native C++, otherwise you're inventing
a new language that has nothing to do with C++. Exactly that happened
with the old MC++, where the destructor syntax was used for the
finalizer. Such a radical change has disadvantages, because C++
programmers have certain expectations about the language, such as the
copy c'tor syntax, even if it's implemented in the underlying .NET layer
differently.

What you're asking for is

cli::auto_ptr<FileStream> fs(fi.OpenRead());

which may or may not exist. If it doesn't, you can try to write your
own. It would have a little bit of an overhead, but only a couple of
extra CLI instructions.

Here's an auto pointer template that I wrote, although it has a
completely different purpose (to store unmanaged objects inside a
managed wrapper):

#pragma once

template <class T>
public ref class CliScopedPtr
{
typedef CliScopedPtr<T> this_type;

public:
CliScopedPtr()
: ptr(nullptr)
{
}

explicit CliScopedPtr(T* p)
: ptr(p)
{
}

~CliScopedPtr()
{
delete ptr;
}

T* get()
{
return ptr;
}

T& operator*()
{
return *ptr;
}

T* operator->()
{
return ptr;
}

bool assigned()
{
return ptr != nullptr;
}

void swap(CliScopedPtr% other)
{
T* tmp = other.ptr;
other.ptr = ptr;
ptr = tmp;
}

void swap(CliScopedPtr^ other)
{
T* tmp = other->ptr;
other->ptr = ptr;
ptr = tmp;
}

void reset()
{
this_type().swap(this);
}

void reset(T* p)
{
this_type(p).swap(this);
}

private:
T* ptr;
CliScopedPtr(CliScopedPtr%); // disabled
CliScopedPtr% operator=(CliScopedPtr%); // disabled
};
Credit goes to boost::scoped_ptr for the idea.

Example:

class Unmanaged { };

CliScopedPtr<Unmanaged> ptr(new Unmanaged);

Tom
Nov 17 '05 #10

"Tamas Demjen" <td*****@yahoo.com> wrote in message
news:%2****************@TK2MSFTNGP14.phx.gbl...
Alexei wrote:
Now, does it matter if the object is created with gcnew or by calling a
function? No, IMO. The same code I can rewrite with using
fi.OpenRead():

{
FileStream ^ fs = fi.OpenRead();
try {
} finally {
delete fs;
}
}


Something like this would be nice, but it can't be done the way you're
trying to do it.
What leads me to simply:

FileStream fs(fi.OpenRead());


I think the code above would expand to

FileStream^ fs = gcnew FileStream(fi.OpenRead());
[...]

and there is no such copy constructor in FileStream (and even if there was
one, you wouldn't want to make a copy in this case).
I can't understand the point of having copy-constructors for ref classes.


There is such a thing as copy c'tor and assignment operator in C++/CLI.
Because what if you want to make a copy? You could always define a static
member (class method) name CopyMe, but C++/CLI was designed to be as
conforming with C++ as possible. The stack syntax with ref classes has to
work like stack objects in native C++, otherwise you're inventing a new
language that has nothing to do with C++. Exactly that happened with the
old MC++, where the destructor syntax was used for the finalizer. Such a
radical change has disadvantages, because C++ programmers have certain
expectations about the language, such as the copy c'tor syntax, even if
it's implemented in the underlying .NET layer differently.

What you're asking for is

cli::auto_ptr<FileStream> fs(fi.OpenRead());

which may or may not exist. If it doesn't, you can try to write your own.
It would have a little bit of an overhead, but only a couple of extra CLI
instructions.

Here's an auto pointer template that I wrote, although it has a completely
different purpose (to store unmanaged objects inside a managed wrapper):

#pragma once

template <class T>
public ref class CliScopedPtr
{
typedef CliScopedPtr<T> this_type;

public:
CliScopedPtr()
: ptr(nullptr)
{
}

explicit CliScopedPtr(T* p)
: ptr(p)
{
}

~CliScopedPtr()
{
delete ptr;
}

T* get()
{
return ptr;
}

T& operator*()
{
return *ptr;
}

T* operator->()
{
return ptr;
}

bool assigned()
{
return ptr != nullptr;
}

void swap(CliScopedPtr% other)
{
T* tmp = other.ptr;
other.ptr = ptr;
ptr = tmp;
}

void swap(CliScopedPtr^ other)
{
T* tmp = other->ptr;
other->ptr = ptr;
ptr = tmp;
}

void reset()
{
this_type().swap(this);
}

void reset(T* p)
{
this_type(p).swap(this);
}

private:
T* ptr;
CliScopedPtr(CliScopedPtr%); // disabled
CliScopedPtr% operator=(CliScopedPtr%); // disabled
};
Credit goes to boost::scoped_ptr for the idea.

Example:

class Unmanaged { };

CliScopedPtr<Unmanaged> ptr(new Unmanaged);

Tom


Guess what, just installed the June CTP of VS2005, and they included exactly
this through the auto_handle template in the msclr namespace.

#include <msclr\auto_handle.h>
....
FileInfo fi("......");
msclr::auto_handle<FileStream> fs(fi.OpenRead());
...

Willy.


Nov 17 '05 #11
Willy Denoyette [MVP] wrote:
Guess what, just installed the June CTP of VS2005, and they included exactly
this through the auto_handle template in the msclr namespace.

#include <msclr\auto_handle.h>
...
FileInfo fi("......");
msclr::auto_handle<FileStream> fs(fi.OpenRead());
..

Willy.


Thank you for the information, it's very good to know. It will solve the
original poster's problem.

My CliSmartPtr, however, is slightly different. auto_handle<T> is a
managed smart pointer around T^. CliSmartPtr<T> is a managed smart
pointer around T*. I intended to use it in situations like

ref class C
{
private:
CliSmartPtr<Unmanaged> unmanaged;
[...]
};

It yet has to be tested with a real-world project. :-)

Tom
Nov 17 '05 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Val3 | last post by:
Hi all. I'm using Microfoft CLR Debugger to test my c# programs. It seems works fine except for one thing. When I try to modify code message "cannot currently modify this text in the editor. It...
28
by: joe | last post by:
I have a simple .NET application with two or three listViews which are filled with icons and when the user click on the proper item, they display the related images. I use "image = null ; " for all...
4
by: Adriano Coser | last post by:
I'm getting the following error: error C3767: PictureSource - candidate function(s) not accessible when accessing a public member function of a managed class, either from managed or unmanaged...
6
by: John Gabriel | last post by:
I have been obtaining the following error in the output window of the IDE: 1>mt.exe:general error c101008d:Failed to write the updated manifest to the resource of file "..\debug\test.exe". The...
1
by: Jürgen Kahrs | last post by:
Hello, The beta alpha release (xgawk-3.1.5-beta.20060401) of the xmlgawk project is now available at SourceForge. http://sourceforge.net/projects/xmlgawk/...
2
by: Randy Kraemer | last post by:
There is a free Beta test of a Python 2.4 Certification test available at Brainbench.com. They are a provider of skills-based certification exams. Go to the link below to find the test. It is free...
11
by: Ken Fine | last post by:
I am using VS.NET 2008 and like it a lot. One of the very few things I don't like is a bug that seems to spawn literally thousands of   strings, one after the other, on design view changes....
4
by: Slickuser | last post by:
How do I automatic move the X & Y to create a ellipse function as below, DrawCircle? Or there any sample source code out there? I want it move down by user input. How can I achieve this?...
8
by: Lemune | last post by:
Hi, I'm developing window service application on C# 2005. The service is to read a new excel file on certain directory, and process it to database. The service work find on XP. But when I...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.