473,734 Members | 2,789 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

assignment operator overload error??

Can someone help me see why the following "operator=" overloading
doesn't work under g++? and the error message is copied here. I see no
reason the compiler complain this. Thanks,

[bash]$ g++ copyconstructor 1.cpp
#copyconstructo r1.cpp: In function `int main()':
#copyconstructo r1.cpp:86: no match for `sample& = sample' operator
#copyconstructo r1.cpp:53: candidates are: sample sample::operato r=(sample&)

=============== =============== ===========
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;

class sample {
char *s;
public:
sample(); // normal constructor
sample(const sample &ob); // copy constructor
~sample( ) { if(s) delete [] s; cout << "Freeing s\n"; }
void show() { cout << s << "\n"; }
void set(char *str);
sample operator=(sampl e &ob); // overload assignment
};

// Normal constructor.
sample::sample( )
{
s = new char('\0'); // s points to a null string.
if(!s) {
cout << "Allocation error\n";
exit(1); // exit program if out of memory
}
}

// Copy constructor.
sample::sample( const sample &ob)
{
s = new char[strlen(ob.s)+1];
if(!s) {
cout << "Allocation error\n";
exit(1); // exit program if out of memory
}
strcpy(s, ob.s);
}

// Load a string.
void sample::set(cha r *str)
{
s = new char[strlen(str)+1];
if(!s) {
cout << "Allocation error\n";
exit(1); // exit program if out of memory
}
strcpy(s, str);
}
sample sample::operato r=(sample &ob)
{
/* If the target string is not large enough
then allocate a new string. */
if(strlen(ob.s) > strlen(s)) {
delete [] s;
s = new char[strlen(ob.s)+1];
if(!s) {
cout << "Allocation error\n";
exit(1); // exit program if out of memory
}
}
strcpy(s, ob.s);
return *this;
}

// Return an object of type sample.
sample input()
{
char instr[80];
sample str;

cout << "Enter a string: ";
cin >> instr;

str.set(instr);
return str;
}

int main()
{
sample ob;

ob = input(); // This doesn't compile under g++
ob.show();

return 0;
}
Sep 29 '05 #1
7 4671
Sean wrote:
Can someone help me see why the following "operator=" overloading
doesn't work under g++? and the error message is copied here. I see no
reason the compiler complain this. Thanks,

A few errors, see comments below.
[bash]$ g++ copyconstructor 1.cpp
#copyconstructo r1.cpp: In function `int main()':
#copyconstructo r1.cpp:86: no match for `sample& = sample' operator
#copyconstructo r1.cpp:53: candidates are: sample sample::operato r=(sample&)

=============== =============== ===========
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;

class sample {
char *s;
public:
sample(); // normal constructor
sample(const sample &ob); // copy constructor
~sample( ) { if(s) delete [] s; cout << "Freeing s\n"; }
void show() { cout << s << "\n"; }
void set(char *str);
sample operator=(sampl e &ob); // overload assignment
Should be

sample operator=(const sample &ob); // overload assignment

You program does not compile because you wrote the assignment operator
with a non-const reference instead of a const reference.

There is a rule in C++ that you cannot bind a temporary to a non-const
reference, so assignment operators and copy constructors (and most other
things) should be writen with const references if possible.
};

// Normal constructor.
sample::sample( )
{
s = new char('\0'); // s points to a null string.
This is wrong. You cannot mixup allocations with new and new[], because
you must free new with delete and new[] with delete[].

This is correct

s = new char[1];
s[0] = '\0';
if(!s) {
This is wrong, new does not return NULL if it fails, instead it throws
an exeption.
cout << "Allocation error\n";
exit(1); // exit program if out of memory
}
}

// Copy constructor.
sample::sample( const sample &ob)
{
s = new char[strlen(ob.s)+1];
if(!s) {
Again, new never returns NULL.
cout << "Allocation error\n";
exit(1); // exit program if out of memory
}
strcpy(s, ob.s);
}

// Load a string.
void sample::set(cha r *str)
{
s = new char[strlen(str)+1];
if(!s) {
cout << "Allocation error\n";
exit(1); // exit program if out of memory
}
strcpy(s, str);
}
This function is ill conceived. It also leaks memory becaise the string
will already have some memory allocated which you don't free.

You should rewrite this as a constructor

sample::sample( const char* str)
{
s = new char[strlen(str)+1];
strcpy(s, str);
}


sample sample::operato r=(sample &ob)
{
/* If the target string is not large enough
then allocate a new string. */
if(strlen(ob.s) > strlen(s)) {
delete [] s;
s = new char[strlen(ob.s)+1];
if(!s) {
Again.
cout << "Allocation error\n";
exit(1); // exit program if out of memory
}
}
strcpy(s, ob.s);
return *this;
}

// Return an object of type sample.
sample input()
{
char instr[80];
sample str;

cout << "Enter a string: ";
cin >> instr;

str.set(instr);
return str;
}
Now if you rewrite sample::set as a constructor this function becomes
really easy

sample int()
{
char instr[80];
cout << "Enter a string: ";
cin >> instr;
return instr;
}

The compiler will create a sample object from the instr array using the
constructor I advised you to write above.

int main()
{
sample ob;

ob = input(); // This doesn't compile under g++
ob.show();

return 0;
}


Above all you need to learn about const.

john
Sep 29 '05 #2
Sean wrote:
Can someone help me see why the following "operator=" overloading
doesn't work under g++? and the error message is copied here. I see no
reason the compiler complain this. Thanks,

[bash]$ g++ copyconstructor 1.cpp
#copyconstructo r1.cpp: In function `int main()':
#copyconstructo r1.cpp:86: no match for `sample& = sample' operator
#copyconstructo r1.cpp:53: candidates are: sample
sample::operato r=(sample&)

=============== =============== ===========
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;

class sample {
char *s;
public:
sample(); // normal constructor
sample(const sample &ob); // copy constructor
~sample( ) { if(s) delete [] s; cout << "Freeing s\n"; }
void show() { cout << s << "\n"; }
void set(char *str);
sample operator=(sampl e &ob); // overload assignment
It's unusual for operator= to return a copy of itself, which you are doing,
but I doubt that that's your problem. It's more likely that the reference
argument is not const. Try making this your operator=:
sample &operator=(cons t sample &ob);
};
[snip]
int main()
{
sample ob;

ob = input(); // This doesn't compile under g++
The compiler probably doesn't like passing the temporary returned by input()
as a non-const reference to the assignment operator. I actually thought the
standard prohibited this, but neither VC++ 6.0 nor VS .NET 2003 is
complaining about it.
ob.show();

return 0;
}


DW
Sep 29 '05 #3
>
The compiler probably doesn't like passing the temporary returned by input()
as a non-const reference to the assignment operator. I actually thought the
standard prohibited this, but neither VC++ 6.0 nor VS .NET 2003 is
complaining about it.


The standard does prevent it. With those compilers you can get the
correct behaviour if you turn on 'disable language extensions', the /Za
options.

john
Sep 29 '05 #4
"John Harrison" <jo************ *@hotmail.com> wrote in message
news:pJ******** ********@newsfe 2-gui.ntli.net...

The compiler probably doesn't like passing the temporary returned by input() as a non-const reference to the assignment operator. I actually thought the standard prohibited this, but neither VC++ 6.0 nor VS .NET 2003 is
complaining about it.


The standard does prevent it. With those compilers you can get the
correct behaviour if you turn on 'disable language extensions', the /Za
options.


Well, that's ridiculous. You should have to _enable_ the extensions with a
switch, not disable. Thanks.

DW

Sep 29 '05 #5
David White wrote:
"John Harrison" <jo************ *@hotmail.com> wrote in message
news:pJ******** ********@newsfe 2-gui.ntli.net...
The compiler probably doesn't like passing the temporary returned by
input()
as a non-const reference to the assignment operator. I actually thought
the
standard prohibited this, but neither VC++ 6.0 nor VS .NET 2003 is
complainin g about it.


The standard does prevent it. With those compilers you can get the
correct behaviour if you turn on 'disable language extensions', the /Za
options.

Well, that's ridiculous. You should have to _enable_ the extensions with a
switch, not disable. Thanks.

DW


Backwards compatibility I think. VC++ 6 could not compile <windows.h>
without 'language extensions'. Don't know if that is still the case but
I wouldn't be surprised.

john
Sep 29 '05 #6
I am studying C++, currently learning to overload the assignment
operator. My text book (by D.S. Malik) teaches that the assignment
operator overload function returns a const reference, but it does not
explain why. In trying to understand this, I see that an address is
passed, and that address is not being changed, but I expect the
overloaded assignment function to change the data referenced by that
address. So I am confused how it can be const.

While goggling for an explaination, I found a recent post where you
helped someone who did not use a const reference in an assignment
overload prototype statement. Could you help me understand what "bind
a temporary to a non-const reference" means?

Dave

sample operator=(sampl e &ob); // overload assignment
Should be

sample operator=(const sample &ob); // overload assignment

You program does not compile because you wrote the assignment operator
with a non-const reference instead of a const reference.

There is a rule in C++ that you cannot bind a temporary to a non-const
reference, so assignment operators and copy constructors (and most other
things) should be writen with const references if possible.
};

... snip
john


Oct 6 '05 #7
Dave wrote:
I am studying C++, currently learning to overload the assignment
operator. My text book (by D.S. Malik) teaches that the assignment
operator overload function returns a const reference, but it does not
explain why.
If the book really makes that claim, it cannot give a reason because the
claim is false:

struct IntWrapper {

int i;

IntWrapper ( int ii = 0 )
: i ( ii )
{}

IntWrapper & inc ( void ) {
++ i;
return ( *this );
}

IntWrapper & operator= ( IntWrapper const & other ) {
i = other.i;
return ( *this );
}

}; // IntWrapper;

#include <iostream>

int main ( void ) {
IntWrapper a ( 5 );
IntWrapper b ( 3 );
( b = a ).inc().inc();
std::cout << b.i << '\n';
}

It also fails for the assignment operator that is automatically provided by
the compiler:
struct IntWrapper {

int i;

IntWrapper ( int ii = 0 )
: i ( ii )
{}

IntWrapper & inc ( void ) {
++ i;
return ( *this );
}

}; // IntWrapper;

#include <iostream>

int main ( void ) {
IntWrapper a ( 5 );
IntWrapper b ( 3 );
( b = a ).inc().inc();
std::cout << b.i << '\n';
}

In trying to understand this, I see that an address is
passed, and that address is not being changed, but I expect the
overloaded assignment function to change the data referenced by that
address. So I am confused how it can be const.

While goggling for an explaination, I found a recent post where you
helped someone who did not use a const reference in an assignment
overload prototype statement. Could you help me understand what "bind
a temporary to a non-const reference" means?


You are confusing three different things:

a) non-constness of the return type.
(it's not necessary to make the return type const)

b) non-constness of the operator= method.
(it usually is necessary to make this method non-const.)

c) constness of the argument type.
(it is usually a good idea to have the argument be const.)
[see auto_ptr<T> for a case where the argument is non-const.]

> sample operator=(sampl e &ob); // overload assignment


Should be

sample operator=(const sample &ob); // overload assignment

You program does not compile because you wrote the assignment operator
with a non-const reference instead of a const reference.

There is a rule in C++ that you cannot bind a temporary to a non-const
reference, so assignment operators and copy constructors (and most other
things) should be writen with const references if possible.


This quote discusses item (c) from above. Neither (a) nor (b) are at issue
here.
Best

Kai-Uwe Bux
Oct 6 '05 #8

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

Similar topics

5
4832
by: CoolPint | last post by:
It seems to me that I cannot assign objects of a class which has a constant data member since the data member cannot be changed once the constructor calls are completed. Is this the way it is meant to be? Am I not suppose not to have any constant data member if I am going to have the assignment operator working for the class? Or am I missing something here and there is something I need to learn about? Clear, easy to understand...
16
2615
by: Edward Diener | last post by:
Is there a way to override the default processing of the assignment operator for one's own __value types ? I realize I can program my own Assign method, and provide that for end-users of my class, but I would like to use internally my own = operator for some of my value types, so I can say "x = y;" rather than "x.Assign(y);". The op_Assign operator seems impossibly broken since it takes __value copies of the two objects. Perhaps there is...
3
1614
by: jim.brown | last post by:
The attached code implements a test class to show an error in overloading operator=. This code works on Windows with Visual Studio and simpler cases work with gcc 3.3.2 on Solaris 9. On Windows, operator= gets called twice and I'm not sure whay that is. This fails on Solaris with: In function 'int main(int, char**)' error: no match for 'operator=' in 't2 = TestCL::getTestCL()()'
9
3375
by: Gyro | last post by:
Dear All! Why there is no operator= for any type? I trying: typedef float mtx; operator=(mtx a, mtx b) { } compiler compaints that error: "operator=" must be a member function
19
2228
by: scroopy | last post by:
Is it impossible in C++ to create an assignment operator for classes with const data? I want to do something like this class MyClass { const int m_iValue; public: MyClass(int iVal):m_iValue(iVal){}
3
1674
by: Abubakar | last post by:
Hi, lets say I have a class called "hashstring". I want to be able to write the following code: hashstring hs ( "hello world" ); char * somecharptr; somecharptr = hs; // here the somecharptr starts pointing to "hello world". is it possible? How do I overload assignment operator such that I'm able to
5
2292
by: raylopez99 | last post by:
I need an example of a managed overloaded assignment operator for a reference class, so I can equate two classes A1 and A2, say called ARefClass, in this manner: A1=A2;. For some strange reason my C++.NET 2.0 textbook does not have one. I tried to build one using the format as taught in my regular C++ book, but I keep getting compiler errors. Some errors claim (contrary to my book) that you cannot use a static function, that you must...
9
3512
by: sturlamolden | last post by:
Python allows the binding behaviour to be defined for descriptors, using the __set__ and __get__ methods. I think it would be a major advantage if this could be generalized to any object, by allowing the assignment operator (=) to be overloaded. One particular use for this would be to implement "lazy evaluation". For example it would allow us to get rid of all the temporary arrays produced by NumPy. For example, consider the...
9
2900
by: puzzlecracker | last post by:
From my understanding, if you declare any sort of constructors, (excluding copy ctor), the default will not be included by default. Is this correct? class Foo{ public: Foo(int); // no Foo() is included, i believe. };
0
9449
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9310
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9236
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9182
tracyyun
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8186
agi2029
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6735
isladogs
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4550
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4809
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3261
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

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.