Hi,
Sorry to bother you again.
I recently read that the operator '=' can't be overloaded in derived classess; but all others can be.
If the info is correct, Why is it so?
There was no explanation in the book but this sentence.
Thanks for any help.
Hi,
Sorry to bother you again.
I recently read that the operator '=' can't be overloaded in derived classess; but all others can be.
If the info is correct, Why is it so?
There was no explanation in the book but this sentence.
Thanks for any help.
Eh...looks fine to me.Code:#include <iostream> using std::cout; using std::endl; class A { public: int m_a; A& operator=(const A& a) { m_a = a.m_a; //assign return *this; } }; class B : public A //B derived from A { public: int m_b; B& operator=(const B& b) { this->A::operator=(b); //call base operator= m_b = b.m_b; //assign return *this; } }; int main() { A a1, a2; B b1, b2; a1.m_a = 2; a2 = a1; cout << a2.m_a << endl; b1.m_a = 3; b1.m_b = 4; b2 = b1; cout << b2.m_a << " " << b2.m_b << endl; return 0; }
If I did your homework for you, then you might pass your class without learning how to write a program like this. Then you might graduate and get your degree without learning how to write a program like this. You might become a professional programmer without knowing how to write a program like this. Someday you might work on a project with me without knowing how to write a program like this. Then I would have to do you serious bodily harm. - Jack Klein
Could this overloaded be derived ?Originally Posted by arjunajay
What do you mean?Could this overloaded be derived ?
pianorain just used the A::=operator();
Did you mean anything else.
2) How come piano rain use b as an argument in the line
this->A:perator=(b);
A:: can't take b as a parameter.
It should be an A object.
b is an A object. Since B is derived from A, and b is a B, then b is also an A.
If I did your homework for you, then you might pass your class without learning how to write a program like this. Then you might graduate and get your degree without learning how to write a program like this. You might become a professional programmer without knowing how to write a program like this. Someday you might work on a project with me without knowing how to write a program like this. Then I would have to do you serious bodily harm. - Jack Klein
How is that possible?
B inherits from A, implies B knows about A and how to handle it; but A don't have any kind of info on B, and moreover, if you pass a B to the A, A has to convert it into a type of A, right? Since A doesn't know any thing abt B how is this possible?
Or is my concept wrong?; cause if it is, then I'd have to go back to square one on inheritance
Last edited by arjunajay; 06-18-2005 at 04:39 AM. Reason: ???
Operator = is not inherited.
The reason for this is both simple and complicated. But since there seems to be a bit of confusion, let's recap.
We'll call our base class B, and the derived class D.
D deriving from B means that it's a more refined concept. It may have more functions, more variables, or just override something from the base.
D also inherits everything from its base. Every function, every variable. Not all of them are accessible to D (private members of B aren't), but they're there, ready for the B subobject to use.
This includes operators.
For example, if it's possible to add two B objects together, there's no reason why you shouldn't add two Ds together. (Just don't expect the result to be a D as well - it's a B unless D redefines the addition operator.)
However, assignment operators are the big exception.
Assignment operators and constructors exist for a reason: to allow assigment of or initialization with values to a class object while maintaining the object's internal consistency.
Let's assume that B stores data for a connection to some server. It has an assignment operator that assigns from a std::string by parsing it into parts:
So far, everything's fine.Code:B & operator =(const std::string &str) { std::string::size_type colpos = str.find(':'); host = str.substr(0, colpos); port = str.substr(colpos+1); return *this; }
D derives from B, and it's used for a very special application of the connection to the server. This special application needs the server's ID very often. This ID can be retrieved by a special call to the server.
While B is fully capable of issuing this call, it's something B doesn't understand. It's just another call to B. D however knows that this ID is used very often, and it also knows that it's always the same for the same server.
So D is smart and retrieves the ID once, and then caches it:
serverID is initially set to "", but when D has retrieved the ID once, it stores it in serverID. On subsequent calls, if serverID is not "", D doesn't contact the server but just returns serverID.Code:class D : public B { std::string serverID; };
What would happen if B's assignment operator was inherited?
So far everything's fine. The getId() call cached the server ID in the object.Code:D specConn; specConn = "localhost:12034"; std::string id = specConn.getId();
This still compiles. However, it doesn't work. B::operator =(const std::string &) assigns to host and port, but serverID stays the same - the cached ID of the old server. Every subsequent operation is corrupted, by a bug that's very, very hard to find.Code:specConn = "otherhost:9248"; std::string id = specConn.getId();
But the assignment operator is not inherited, luckily. The above code fails to compile. This is a partial security measure against such things.
I say partial, because it's still possible to trick the system!
Same bug, no compile error. The responsibility is yours.Code:D specConn; B &refConn = specConn; refConn = "localhost:12034";
All the buzzt!
CornedBee
"There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
- Flon's Law
Have you read anything about what's called "polymorphism" yet? It works by assigning a derived class object to a base class pointer. For instance,How is that possible?
B inherits from A, implies B knows about A and how to handle it; but A don't have any kind of info on B, and moreover, if you pass a B to the A, A has to convert it into a type of A, right? Since A doesn't know any thing abt B how is this possible?
Or is my concept wrong?; cause if it is, then I'd have to go back to square one on inheritance
There is also a phenomenon known as object slicing:Code:#include <iostream> #include <string> using namespace std; class Fruit { public: virtual void display() { cout<<"Fruit class"<<endl; } void shout() { cout<<"Fruit: I'm not an aniiiimal! I'm a piece of fruit!"<<endl; } }; class Apple : public Fruit { public: void display() //overrides { cout<<"Apple class."<<endl; } void greeting() { cout<<"Hi, I'm an apple. What are you?"<<endl; } }; int main() { Apple a; //Apple functions: a.display(); a.greeting(); //Apple function inherited from Fruit: a.shout(); //Polymorphism: Fruit* ptr = &a; cout<<endl; ptr->display(); //Apple version is called return 0; }
Code:int main() { Apple a; //Apple functions: a.display(); a.greeting(); //Apple function inherited from Fruit: a.shout(); //Polymorphism: Fruit* ptr = &a; cout<<endl; ptr->display(); //Object slicing: Fruit f = a; f.display(); //Fruit version of display() is called f.greeting(); //error: greeting() is not a member of Fruit return 0; }
Last edited by 7stud; 06-18-2005 at 12:15 PM.
Does this mean that one has to rewrite the asginment operator again from scratch in a derived class in order to make it work as it should?But the assignment operator is not inherited, luckily.
Yes; but only the addres of the obj: is asgined to a pointer. which implies that no real asginment of data members occur, and that during runtime the prgram decies what to execute, which also implies that no loss of data occurs(see below). It never came to my mind as I have almost never used it.Have you read anything about what's called "polymorphism" yet? It works by assigning a derived class object to a base class pointer. For instance,
Sorry I haven't heard of it. Besides it causes deletion of data (like asgining a double to an int causing truncation of decimal places with out even rounding).There is also a phenomenon known as object slicing:
P.S.
My Brain HURTS (@ @)!
Last edited by arjunajay; 06-20-2005 at 06:17 AM. Reason: tag
Depends. The standard assignment operator (the one taking the class itself) is automatically generated to first call the base version and then call it for every member of the derived class.Does this mean that one has to rewrite the asginment operator again from scratch in a derived class in order to make it work as it should?
However, custom assignment operators must be re-implemented. You can still explicitely call the base version, though. For example, in my case you could do:
Code:class D : public B { D &operator =(const std::string &str) { B::operator =(str); serverId.clear(); return *this; } };
All the buzzt!
CornedBee
"There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
- Flon's Law