Oh, I did not read your code carefully.Quote:
My code is posted in #18. It breaks this rule.
Anything wrong? Appreciated if you could point out.
Of course something is wrong. Try creating a GraphNode object.
Printable View
Oh, I did not read your code carefully.Quote:
My code is posted in #18. It breaks this rule.
Anything wrong? Appreciated if you could point out.
Of course something is wrong. Try creating a GraphNode object.
Thanks laserlight,
1.
I have verified the code you posted. Here is the compile error.Quote:
Originally Posted by laserlight
error C2440: 'initializing' : cannot convert from 'const int' to 'int &'
So, I think it breaks the C++ rule that can not bind non-const reference to a const value variable, right?
int& ra = a;
But, I do not know does this rule have anything to do with passing parameter to foo? You can see the above line compile fails in main, before passing parameter to function goo.
2.
"in this case" you mean when base class destructor is invoked from derived class?Quote:
Originally Posted by laserlight
regards,
George
Thanks laserlight,
My bad. I have tried. Compile ok but link error. Here is the error information and related code.
So the fix is to implement the destructor in base class GraphPart, right? My understanding and code are correct?
1>main.obj : error LNK2019: unresolved external symbol "public: virtual __thiscall GraphPart::~GraphPart(void)" (??1GraphPart@@UAE@XZ) referenced in function "public: virtual __thiscall GraphNode::~GraphNode(void)" (??1GraphNode@@UAE@XZ)
Code:#include <string>
#include <iostream>
using namespace std;
class GraphPart
{
public:
virtual void setField(std::string fieldname, std::string value)=0;
virtual bool cmpField(std::string fieldname, std::string value) const=0;
virtual const char* getField(std::string fieldname) const=0;
virtual ~GraphPart() = 0;
};
class GraphNode: public GraphPart
{
public:
// data is a mix of non-pointer primitives and STL containers, nothing else
void setField(std::string fieldname, std::string value) {};
bool cmpField(std::string fieldname, std::string value) const {return true;};
const char* getField(std::string fieldname) const {return NULL;};
};
class GraphEdge: public GraphPart
{
public:
// data is non-pointer primitives
void setField(std::string fieldname, std::string value) {};
bool cmpField(std::string fieldname, std::string value) const {return true;};
const char* getField(std::string fieldname) const {return NULL;};
};
int main()
{
GraphNode gn;
return 0;
}
Quote:
Originally Posted by laserlight
regards,
George
angelorohit's main point is that to the caller:Quote:
But, I do not know does this rule have anything to do with passing parameter to foo? You can see the above line compile fails in main, before passing parameter to function goo.
is no different from:Code:int goo(const int input);
There const keyword only makes a difference for:Code:int goo(int input);
versus:Code:int goo(const int& input);
angelorohit's side point, which you seem to be having so much trouble with, is that you cannot write:Code:int goo(int& input);
If you find it easier to understand, just ignore angelorohit's side point. It has nothing to do with your actual code, but is an observation of what you did not, and cannot, do.Code:int foo(int& input)
{
return input;
}
int main()
{
const int a = 0;
foo(a);
}
Yes. Note that there is no actual override as is normal for virtual functions. Rather, the derived class destructor invokes the base class destructor, as per the normal routine for object destruction.Quote:
"in this case" you mean when base class destructor is invoked from derived class?
Thanks laserlight,
1.
Your below comments about reference and value are great! I have made exercise.
1.1 For the value, no differences between const and non-const is because there is a copy made on the input parameter, not caring the original one and operating on the original one in the function;
1.2 For the reference, since function will operate on the original one, so it matters about const property -- we can make the variable more strict, but not more loose;
Any code and understanding are correct? :-)
2.Code:int goo1 (const int input)
{
return 1;
}
int goo2 (int input)
{
return 2;
}
int goo3 (const int& input)
{
return 3;
}
int goo4 (int& input)
{
return 4;
}
void gooTest()
{
const int a = 100;
goo1(a); // compile ok
goo2(a); // compile ok
goo3 (a); // compile ok
goo4 (a); // error C2664: 'goo4' : cannot convert parameter 1 from 'const int' to 'int &'
return;
}
about your comments,
"Note that there is no actual override as is normal for virtual functions.", I am interested what do you mean no actual overrides? Could you provide more information please?
In my mind, when you create an instance of derived object instance, and assign it to a base class pointer, then call the destructor, then the derived class' destructor is called, so it has overridding effect. What is your point?
Quote:
Originally Posted by laserlight
regards,
George
Thanks laserlight for clearing George2's doubts from my end. For some reason, I wasn't getting the notification e-mail from this thread and I overslept today. :D
Thanks to laserlight the same, I feel I learned a lot from this thread. :-)
Quote:
Originally Posted by angelorohit
regards,
George
Yes, you are correct. The derived class destructor does override the base class destructor if the latter is declared virtual.Quote:
In my mind, when you create an instance of derived object instance, and assign it to a base class pointer, then call the destructor, then the derived class' destructor is called, so it has overridding effect.
WRONG!!!!Quote:
Originally Posted by George2
You are passing an integer by value. What is passed is totally controlled by the method declaration. The parameter has nothing to do with it (diectly).
Your variable "ra" is a reference to your variable "a" which contains the value 100. So you are passing a copy of the value 100 to the method.
If you want to pass a const reference:
If you want to pass a non-const reference:Code:virtual int goo (const int &input) {...}
Once again your utter lack of understanding of the most basic trminology and functionallity is causing you to make fundamental mistakes. Why are you so insistant on not getting a good book, and actually trying to learn the basics??????Code:virtual int goo (int& input) {...}
Sorry TheCPUWizard,
It is my carelessness in yesterday's flood of discussion. It is basic things and surely I understand. :-)
Quote:
Originally Posted by TheCPUWizard
regards,
George
Hi laserlight,
Sorry I do not agree with you. Even if we define the base class's destructor as pure virtual (not virtual as you mentioned), there is still expected virtual function behavior. Here is the code and output, any comments?
I am confused what do you mean "Note that there is no actual override as is normal for virtual functions."? Any special behavior when we define base class's destructor as pure virtual?
output:Code:#include <string>
#include <iostream>
using namespace std;
class GraphPart
{
public:
virtual void setField(std::string fieldname, std::string value) {};
virtual bool cmpField(std::string fieldname, std::string value) const {return true;}
virtual const char* getField(std::string fieldname) const {return NULL;}
virtual ~GraphPart() = 0;
};
/*
If remove the following destructor implementation, there will be link error, about unresolved reference to destructor of class GraphPart
*/
GraphPart::~GraphPart()
{
cout << "GraphPart " << endl;
}
class GraphNode: public GraphPart
{
public:
// data is a mix of non-pointer primitives and STL containers, nothing else
void setField(std::string fieldname, std::string value) {};
bool cmpField(std::string fieldname, std::string value) const {return true;}
const char* getField(std::string fieldname) const {return NULL;}
~GraphNode()
{
cout << "GraphNode " << endl;
}
};
class GraphEdge: public GraphPart
{
public:
// data is non-pointer primitives
void setField(std::string fieldname, std::string value) {};
bool cmpField(std::string fieldname, std::string value) const {return true;}
const char* getField(std::string fieldname) const {return NULL;}
};
int main()
{
GraphNode gn;
GraphPart* pgp = &gn;
return 0;
}
GraphNode
GraphPart
Quote:
Originally Posted by laserlight
regards,
George
As I noted, your interpretation that the derived class destructor overrides the base class destructor is correct (I double checked the standard). What I should have highlighted was that the base class destructor is not inherited, so the override mechanism is not quite the same as normal since the derived class destructor still invokes the base class destructor.Quote:
Sorry I do not agree with you. Even if we define the base class's destructor as pure virtual (not virtual as you mentioned), there is still expected virtual function behavior. Here is the code and output, any comments?
I am confused what do you mean "Note that there is no actual override as is normal for virtual functions."? Any special behavior when we define base class's destructor as pure virtual?
In this respect, it does not matter if the base class destructor is defined as pure virtual or just virtual: the override happens either way, and either way the derived class destructor invokes the base class destructor.
Thanks laserlight,
I think you mean,
1. in normal overriding, derived class hides the methods of base class, so when we invoke the methods on derived class, just the method in derived class is invoked;
2. in destructor overridding, when we call destructor of derived class, the destructor method in base class is not hidden, and still invoked by derived class' destructor?
Is that what you mean?
Quote:
Originally Posted by laserlight
regards,
George
I am not sure if hidden is the right word, but yes, that is what I mean.Quote:
Is that what you mean?
Thanks laserlight,
My question is answered. Thanks for your long help.Quote:
Originally Posted by laserlight
regards,
George