 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
rakesh Guest
|
Posted: Fri Aug 27, 2004 12:58 pm Post subject: constant reference to auto_ptr |
|
|
I'm trying to pass a constant reference to auto_ptr
class CStrClass
{
public:
CStrClass(string str) : m_str(str)
{
cout << "Constructing Temp Class" << endl;
};
~CStrClass( )
{
cout << "Destructing Temp Class" << endl;
};
string getString()
{
return m_str;
};
void setString(string str)
{
m_str = str;
};
void print() const
{
cout<<"Printn"<
};
private:
string m_str;
};
//void TestMedAutoptr ( const auto_ptr
void function (const auto_ptr<const CStrClass>& pi )
{
pi->print();
}
void CConstDlg::OnAutoptr()
{
auto_ptr<CStrClass> pi ( new CStrClass( "Old String" ) );
cout << (pi->getString()).c_str() <<"t"<< endl;
function( pi );
cout << (pi->getString()).c_str() <<"t"<< endl;
}
As soon as the execution comes out of function(pi). The auto_ptr is destroyed.
How do I pass it as a const so that the contents of the objects are not changed
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Maxim Yegorushkin Guest
|
Posted: Sat Aug 28, 2004 2:41 am Post subject: Re: constant reference to auto_ptr |
|
|
rakesh <rak_ash (AT) yahoo (DOT) com> wrote:
[]
| Quote: | void function (const auto_ptr<const CStrClass>& pi )
{
pi->print();
}
void CConstDlg::OnAutoptr()
{
auto_ptr<CStrClass> pi ( new CStrClass( "Old String" ) );
cout << (pi->getString()).c_str() <<"t"<< endl;
function( pi );
cout << (pi->getString()).c_str() <<"t"<< endl;
}
|
[]
| Quote: | As soon as the execution comes out of function(pi). The auto_ptr is destroyed.
How do I pass it as a const so that the contents of the objects are not changed
|
Because auto_ptr
But there is a more fundamental issue with the code.
Most smart pointers imply ownership issues. People use smart pointers in interfaces and function declarations to state the fact that those functions deal with ownership, that is to take the ownership of an object (which exactly the case with functions taking auto_ptr's) or to share it (when functions take pointers with shared ownership semantics).
However, here your function does not deal with ownership, that is, it neither takes ownership nor shares the object, so using a smart pointer in its definition means sending wrong message about function's intent.
The question is why do you want to drop in ownership issues in your function if it in fact does not care about ownership? It looks like you are pretty much better off using a plain reference. (reference looks better here than pointer because you get nicer syntax calling function(*pi) instead of function(pi.get()))
--
Maxim Yegorushkin
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Martin Vorbrodt Guest
|
Posted: Sat Aug 28, 2004 2:46 am Post subject: Re: constant reference to auto_ptr |
|
|
void function(auto_ptr<CStrClass>& pi) { ... }
That works on my gcc 3.2.2 with -ansi -pedantic flags which should imply
maximum standard compliance.
although it is a horrible thing to pass an auto_ptr to a function and expect
it to be alive once the function complets... (read up on Source and Sink
functions and how auto_ptr helps implement them, also resource ownership).
instead try this:
void function(CStrClass* pi) { ... }
autp_ptr<CStrClass> ble(new CStrClass("blebleble"));
function(ble);
function(ble);
this should work just fine, since function() will not take ownership of the
pointer.
Martin
"rakesh" <rak_ash (AT) yahoo (DOT) com> wrote
| Quote: | I'm trying to pass a constant reference to auto_ptr
class CStrClass
{
public:
CStrClass(string str) : m_str(str)
{
cout << "Constructing Temp Class" << endl;
};
~CStrClass( )
{
cout << "Destructing Temp Class" << endl;
};
string getString()
{
return m_str;
};
void setString(string str)
{
m_str = str;
};
void print() const
{
cout<<"Printn"<
};
private:
string m_str;
};
//void TestMedAutoptr ( const auto_ptr
void function (const auto_ptr<const CStrClass>& pi )
{
pi->print();
}
void CConstDlg::OnAutoptr()
{
auto_ptr<CStrClass> pi ( new CStrClass( "Old String" ) );
cout << (pi->getString()).c_str() <<"t"<< endl;
function( pi );
cout << (pi->getString()).c_str() <<"t"<< endl;
}
As soon as the execution comes out of function(pi). The auto_ptr is
destroyed.
How do I pass it as a const so that the contents of the objects are not
changed
|
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Conrad Weyns Guest
|
Posted: Sat Aug 28, 2004 3:06 am Post subject: Re: constant reference to auto_ptr |
|
|
"rakesh" <rak_ash (AT) yahoo (DOT) com> wrote
| Quote: | I'm trying to pass a constant reference to auto_ptr
class CStrClass
{
[...]
};
void function (const auto_ptr<const CStrClass>& pi )
{
pi->print();
}
|
Make a note of the const in: <const CStrClass>
| Quote: |
void CConstDlg::OnAutoptr()
{
auto_ptr<CStrClass> pi ( new CStrClass( "Old String" ) );
cout << (pi->getString()).c_str() <<"t"<< endl;
function( pi );
|
pi is non-const. Your compiler is converting from a auto_ptr
an auto_ptr<const CStrClass> and as you probably know, an auto_ptr takes
over ownership.
A smart_ptr would probably be a better choice?
Regards,
Conrad Weyns.
| Quote: | cout << (pi->getString()).c_str() <<"t"<< endl;
}
As soon as the execution comes out of function(pi). The auto_ptr is
destroyed.
How do I pass it as a const so that the contents of the objects are not
changed |
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Niklas Borson Guest
|
Posted: Sat Aug 28, 2004 3:15 am Post subject: Re: constant reference to auto_ptr |
|
|
[email]rak_ash (AT) yahoo (DOT) com[/email] (rakesh) wrote in message news:<d973e2a6.0408270144.437cba26 (AT) posting (DOT) google.com>...
| Quote: |
void function (const auto_ptr<const CStrClass>& pi )
{
pi->print();
}
|
Note the template parameter in the above function declaration. The
auto_ptr's element_type is "const CStrClass".
| Quote: |
void CConstDlg::OnAutoptr()
{
auto_ptr<CStrClass> pi ( new CStrClass( "Old String" ) );
|
In the above declaration, the template parameter is simply "CStrClass"
(no const); in short, they're not the same type of auto_ptr.
| Quote: | cout << (pi->getString()).c_str() <<"t"<< endl;
function( pi );
|
The local variable pi can't be bound to the refererence parameter
because the underlying types differ. That is, auto_ptr
is not the same type as auto_ptr<const CStrClass>.
However, auto_ptr has an conversion operator that I think is
being used here. If T* is convertable to U* then an auto_ptr<T>
is convertable to an auto_ptr<U> using this operator. So what's
happening here is this:
1. The conversion operator is invoked to create a temporary
object of type auto_ptr<const CStrClass>. Ownership of
the raw pointer is transferred from pi to the temporary.
2. The temporary is bound to the const reference parameter,
and the function is called.
3. At the end of the full expression the temporary passes
out of scope and its desturctor deletes the pointer.
| Quote: | cout << (pi->getString()).c_str() <<"t"<< endl;
}
As soon as the execution comes out of function(pi). The auto_ptr is destroyed.
How do I pass it as a const so that the contents of the objects are not changed
|
You could change the declaration of function to:
void function (const auto_ptr
However, this is still fragile because you can get unexpected behavior if the
types differ slightly (as you've found). Personally I never use auto_ptr in
parameters unless I actually intend to transfer ownership. Instead, I would
either declare the function parameter as a "const CStrClass*" and call it thus:
function(pi.get());
Or if it could never be null, I'd declare the parameter a "const CStrClass&"
and call it thus:
function(*pi);
--Nick
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Conrad Weyns Guest
|
Posted: Sat Aug 28, 2004 10:59 am Post subject: Re: constant reference to auto_ptr |
|
|
"rakesh" <rak_ash (AT) yahoo (DOT) com> wrote
| Quote: | I'm trying to pass a constant reference to auto_ptr
|
[...]
| Quote: | void function (const auto_ptr<const CStrClass>& pi )
{
pi->print();
}
void CConstDlg::OnAutoptr()
{
auto_ptr<CStrClass> pi ( new CStrClass( "Old String" ) );
cout << (pi->getString()).c_str() <<"t"<< endl;
function( pi );
|
The following may be of interest to this issue:
1- Metrowerks CodeWarrior 9.2 rejects it:
Error : ambiguous access to overloaded function
'std::auto_ptr
CStrClass>()'
'std::auto_ptr<const
CStrClass>::auto_ptr<CStrClass>(std::auto_ptr<CStrClass> &)'
main.cpp line 147 function( pi );
2 - MS VC7 (Max warning level) buys it.
3 - gcc (as found in the dev-cpp ide) buys it.
4 - Online Comeau rejects it:
"ComeauTest.c", line 43: error: more than one user-defined conversion from
"std::auto_ptr<CStrClass>" to "const std::auto_ptr<const
CStrClass>"
applies:
function template "std::auto_ptr<_Tp>::operator
std::auto_ptr<_Tp1>() [with _Tp=CStrClass]"
function template
"std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr<_Tp1> &)
[with _Tp=const CStrClass]"
function( pi );
^
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|