As a possible solution to a problem I'm trying to solve with an
iterator (see an earlier post by me with subject "Iterator
implementation questions: copy constructor and postfix increment"),
I'm trying to implement an object that transfers ownership on
assignment or copy, just like auto_ptr does.
With an auto_ptr, I can do this:
#include <string>
#include <memory>
#include <iostream>
using namespace std;
auto_ptr<stringap_factory() {
return auto_ptr<string>(new string("foo"));
}
int main() {
auto_ptr<strings = ap_factory();
auto_ptr<strings2 = s;
cout << "s1=" << s.get() << ", s2=" << *s2 << endl;
}
and when "s2 = s" executes, the pointer that was held by "s" is
trasferred to "s2", and then the pointer in "s" is set to NULL. So, I
see this output:
s1=0, s2=foo
When I try to implement the same behavior in my own class, I have
compilation problems. Here's my small test case:
#include <string>
#include <iostream>
using namespace std;
class C {
public:
C(string *_s) : s(_s) { }
C(C &that) : s(that.s) { }
C& operator=(C &that) {
if (&that != this) {
s = that.s;
}
return *this;
}
const string *get() {
return s.get();
}
private:
auto_ptr<strings;
};
C c_factory() {
return C(new string("foo"));
}
int main() {
C myC = c_factory();
C myC2 = myC;
cout << "myC=" << myC.get() << ", myC2 = " << *(myC2.get()) << endl;
return 0;
}
When I try to compile this, I get:
test8.C: In function C c_factory():
test8.C:28: error: no matching function for call to C::C(C)
test8.C:10: note: candidates are: C::C(C&)
test8.C:8: note: C::C(std::string*)
test8.C: In function int main():
test8.C:32: error: no matching function for call to C::C(C)
test8.C:10: note: candidates are: C::C(C&)
test8.C:8: note: C::C(std::string*)
The problem seems to be that class C doesn't have a copy constructor
for "const C&" but only "C&", which is appropriate since the copied
object will be destroyed. I can verify this is the problem by
creating a constructor for "const C&", and making s mutable so I can
change it without the compiler complaining:
#include <string>
#include <iostream>
using namespace std;
class C {
public:
C(string *_s) : s(_s) { }
C(C const &that) : s(that.s) { }
C& operator=(C &that) {
if (&that != this) {
s = that.s;
}
return *this;
}
const string *get() {
return s.get();
}
private:
mutable auto_ptr<strings;
};
C c_factory() {
return C(new string("foo"));
}
int main() {
C myC = c_factory();
C myC2 = myC;
cout << "myC=" << myC.get() << ", myC2 = " << *(myC2.get()) << endl;
return 0;
}
compiles and gives the expected output:
myC=0, myC2 = foo
Clearly, though, using "mutable" in this way is a hack.
Is there a better solution to this problem? auto_ptr seems not to have
a copy constructor that requires a const object, so there must be a
way, but I've looked at the source code for g++'s auto_ptr and can't
figure out what magic is making this work.
Thanks for any advice,
----ScottG. 7 1794
Scott Gifford wrote:
As a possible solution to a problem I'm trying to solve with an
iterator (see an earlier post by me with subject "Iterator
implementation questions: copy constructor and postfix increment"),
I'm trying to implement an object that transfers ownership on
assignment or copy, just like auto_ptr does.
With an auto_ptr, I can do this:
#include <string>
#include <memory>
#include <iostream>
using namespace std;
auto_ptr<stringap_factory() {
return auto_ptr<string>(new string("foo"));
}
int main() {
auto_ptr<strings = ap_factory();
auto_ptr<strings2 = s;
cout << "s1=" << s.get() << ", s2=" << *s2 << endl;
}
and when "s2 = s" executes, the pointer that was held by "s" is
trasferred to "s2", and then the pointer in "s" is set to NULL. So, I
see this output:
s1=0, s2=foo
When I try to implement the same behavior in my own class, I have
compilation problems. Here's my small test case:
#include <string>
#include <iostream>
using namespace std;
class C {
public:
C(string *_s) : s(_s) { }
C(C &that) : s(that.s) { }
C& operator=(C &that) {
if (&that != this) {
s = that.s;
}
return *this;
}
const string *get() {
return s.get();
}
private:
auto_ptr<strings;
};
C c_factory() {
return C(new string("foo"));
}
int main() {
C myC = c_factory();
Here you have a temporary from which you're trying to construct
an object. That operation requires binding a non-const reference
to the temporary, which is prohibited.
Take a look at how 'auto_ptr' is implemented and follow that instead
of trying to wrap it up.
C myC2 = myC;
cout << "myC=" << myC.get() << ", myC2 = " << *(myC2.get()) <<
endl;
return 0;
}
[..]
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
"Victor Bazarov" <v.********@comAcast.netwrites:
Scott Gifford wrote:
[...]
> C c_factory() { return C(new string("foo")); }
[...]
Here you have a temporary from which you're trying to construct
an object. That operation requires binding a non-const reference
to the temporary, which is prohibited.
I assume you mean the above snippet? I can fix this particular error
by replacing using a temporary:
C c_factory() {
C tmp(new string("foo"));
return tmp;
}
but one error still remains:
test8.C: In function int main():
test8.C:33: error: no matching function for call to C::C(C)
test8.C:10: note: candidates are: C::C(C&)
test8.C:8: note: C::C(std::string*)
Take a look at how 'auto_ptr' is implemented and follow that instead
of trying to wrap it up.
The actual code contains more member variables and methods, so it's
not quite as simple as what I posted. Since the auto_ptr code is
nontrivial and I don't understand all of it, I suspect it would be too
error-prone to try and copy its implementation into my class. I will
probably contine using the "mutable" hack if there's not a
straightforward way to make this work.
Thanks again, Victor!
----Scott.
Scott Gifford wrote:
"Victor Bazarov" <v.********@comAcast.netwrites:
>Scott Gifford wrote:
[...]
>> C c_factory() { return C(new string("foo")); }
[...]
>Here you have a temporary from which you're trying to construct an object. That operation requires binding a non-const reference to the temporary, which is prohibited.
I assume you mean the above snippet? I can fix this particular error
by replacing using a temporary:
C c_factory() {
C tmp(new string("foo"));
return tmp;
}
The variable you call 'tmp' has nothing to do with the "temporary" that
I refered to. A temporary object and an object with automatic storage
duration are not the same. Your 'tmp' here is the latter. The former
is created as the function returns a value.
>
but one error still remains:
test8.C: In function int main():
test8.C:33: error: no matching function for call to C::C(C)
test8.C:10: note: candidates are: C::C(C&)
test8.C:8: note: C::C(std::string*)
>Take a look at how 'auto_ptr' is implemented and follow that instead of trying to wrap it up.
The actual code contains more member variables and methods, so it's
not quite as simple as what I posted. Since the auto_ptr code is
nontrivial and I don't understand all of it, I suspect it would be too
error-prone to try and copy its implementation into my class. I will
probably contine using the "mutable" hack if there's not a
straightforward way to make this work.
In case you don't read my other reply, think reference counting instead
of transfer of ownership.
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Victor Bazarov wrote:
Scott Gifford wrote:
>"Victor Bazarov" <v.********@comAcast.netwrites:
>>Scott Gifford wrote:
[...]
>>> C c_factory() { return C(new string("foo")); }
[...]
>>Here you have a temporary from which you're trying to construct an object. That operation requires binding a non-const reference to the temporary, which is prohibited.
I assume you mean the above snippet? I can fix this particular error by replacing using a temporary:
C c_factory() { C tmp(new string("foo")); return tmp; }
The variable you call 'tmp' has nothing to do with the "temporary" that
I refered to. A temporary object and an object with automatic storage
duration are not the same. Your 'tmp' here is the latter. The former
is created as the function returns a value.
Victor,
adding this information may help understanding the problem.
initial value of reference to non-const must be an lvalue
(the compiler assume that you will somewhere modify the original data)
the temporary returned by the function is an rvalue.
--
Thanks
Barry
The original code posted at the top of the thread, compiles on the
MSVC 8 compiler!!
without errors
Does that compiler then allow binding of temporary to non const??
dev_15 wrote:
The original code posted at the top of the thread, compiles on the
MSVC 8 compiler!!
without errors
Does that compiler then allow binding of temporary to non const??
The MSVC has a compile option /Za, which disables the extension. Maybe
that's for some backward compatibility, I guess.
Try it out.
--
Thanks
Barry
On Sep 7, 3:37 am, James Kanze <james.ka...@gmail.comwrote:
>
The need for "move" semantics (a copy where the source will
never be used again) are more general, and the language is being
modified to support them.
In c++0x, there will be a smart pointer called std::unique_ptr. It is
not Assignable or Copyable but is Moveable.
i.e.
std::unique_ptr<intp1(new int);
std::unique_ptr<intp2;
std::unique_ptr<intp3(p1); //illegal
p2 = p1; //illegal
p2 = std::move(p1); // legal, p1 transfers ownership to p2
std::unique_ptr<intp4(std::move(p2)); // legal, p2 transfers
ownership to p4
Chris
P.S. it will also support custom deleters objects. a "deleter" is a
functor with operator()(T* t). std::default_delete basically does
operator(T* t){delete t;} (or delete [] t if T is of type T[] or T[N]
for some int N). This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: A |
last post by:
Hi,
I have always been taught to use an inialization list for initialising data
members of a class. I realize that initialsizing primitives and pointers use
an inialization list is exactly the...
|
by: Tony Johansson |
last post by:
Hello!
Assume I have a class named Student and I instansiate an object called kasia
in this way.
Student kasia(100);
What the difference if I instead instansiate this kasia in this way....
|
by: jakub.pieczonka |
last post by:
I have three classes in my example. Foo, FooRepository and FooImpl.
Foo is a lightweight wrapper around FooImpl. The idea is that Foo
can be used to pass elements by value from FooRepository to...
|
by: jimjim |
last post by:
Hello,
This is a simple question for you all, I guess .
int main(){
double *g= new double;
*g = 9;
delete g;
cout<< sizeof(g)<<" "<<sizeof(double)<<" "<<sizeof(*g)<<" "<<*g<<" "<<endl;
*g =...
|
by: Bart Simpson |
last post by:
I have the ff class decl:
class ArrayData : public myArray
{
public:
inline ArrayData(){ InitArray(&m_arr);}
inline explicit ArrayData(const std::string& name):m_name(name){...
|
by: Jess |
last post by:
Hello,
If I create a temporary object using a dynamically created object's
pointer, then when the temporary object is destroyed, will the
dynamically created object be destroyed too? My guess...
|
by: Summercool |
last post by:
The meaning of a = b in object oriented languages.
====================================================
I just want to confirm that in OOP, if a is an object, then b = a is
only copying the...
|
by: Stodge |
last post by:
Hi folks, new to Boost Python and struggling to build a prototype at
work. I thought I'd start with a conceptual question to help clarify
my understanding. I already have a basic prototype working...
|
by: Astley Le Jasper |
last post by:
Sorry for the numpty question ...
How do you find the reference name of an object?
So if i have this
bob = modulename.objectname()
how do i find that the name is 'bob'
|
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
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: Sonnysonu |
last post by:
This is the data of csv file
1 2 3
1 2 3
1 2 3
1 2 3
2 3
2 3
3
the lengths should be different i have to store the data by column-wise with in the specific length.
suppose the i have to...
|
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,...
|
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: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
| |