|
-
August 26th, 2002, 11:26 AM
#1
new and polymorphism
Hi,
I am doing too much coding with MFC, thus I have kind of forgotten some real object coding with C++. I have a little question about polymorphism with the new operator:
Say I have these three classes:
Code:
class A {...}; //this is a pure virtual class
class A1: public A {...};
class A2 : public A {...};
I want to do something like this:
Code:
BOOL my_function(A param)
{
//A* m_pA
m_pA = new ???;
*m_pA = param;
}
I don't know before hand what derived type of A the parameter will be, but I must create a new object of this type. The definitions of the classes have no real importance. The only solution I have so far is to have an attribute in A that gives the sub type (initialized in the Ctor, cannot be modified). Then I check on this type to make the proper new:
Code:
switch( param.type)
{
case type_1: m_pA = new A1; break;
case type_2: m_pA = new A2; break;
}
What's the "correct or best" "OO or C++" solution for that?
I would have another solution using a static function as an object factory...
Elrond
A chess genius is a human being who focuses vast, little-understood mental gifts and labors on an ultimately trivial human enterprise.
-- George Steiner
-
August 26th, 2002, 11:42 AM
#2
Have a virtual "clone" member function in the base class.
Code:
class A {
public:
virtual A* clone() = 0;
};
//this is a pure virtual class
class A1: public A
{
public:
A* clone() { return new A1; }
};
class A2 : public A
{
public:
A* clone() { return new A2; }
};
BOOL my_function(A param)
{
A* m_pA;
m_pA = param.clone(); // calls the right clone function
}
Regards,
Paul McKenzie
-
August 26th, 2002, 11:54 AM
#3
That's a step further than the object factory I was thinking about. Using real polymorphism as it should be.  
Thanks a lot Paul.
Elrond
A chess genius is a human being who focuses vast, little-understood mental gifts and labors on an ultimately trivial human enterprise.
-- George Steiner
-
August 26th, 2002, 12:48 PM
#4
Is there a typo in there? Shouldn't you be passing a reference/pointer into my_function?
Thanks,
John
-
August 26th, 2002, 01:11 PM
#5
Preferrable, but not necessary. const reference would be better, and also make clone() a const method. However, everything should work as stated.
Also, you may want to invoke the copy constructor instead of the regular constructor, as in
...
return new A1(*this);
...
etc.
Jeff
-
August 26th, 2002, 01:16 PM
#6
Are you sure? I would think the compiler would complain about trying to instantiate a class that has a pure virtual function.
Reagrds,
John
-
August 26th, 2002, 07:36 PM
#7
Are you sure? I would think the compiler would complain about trying to instantiate a class that has a pure virtual function.
You are right. But please forgive Paul. He is known to frequently post typo's in his sample code. As I says before, I NEVER premise that Paul does NOT know it. I only premise that Paul keep forgetting, even though he KNOWS it.
To any one asking, parameter to
my_function()
should NOT be a pass-by-value parameter of class A, since you can never instantiate A which contains a pure virtual function.
-
August 26th, 2002, 07:48 PM
#8
Are you sure? I would think the compiler would complain about trying to instantiate a class that has a pure virtual function.
Umm, oh yeah... <removes foot from mouth>
Jeff
-
August 26th, 2002, 08:58 PM
#9
Originally posted by AnthonyMai
You are right. But please forgive Paul. He is known to frequently post typo's in his sample code. As I says before, I NEVER premise that Paul does NOT know it. I only premise that Paul keep forgetting, even though he KNOWS it.
To any one asking, parameter to
my_function()
should NOT be a pass-by-value parameter of class A, since you can never instantiate A which contains a pure virtual function.
All this coming from someone who is factually wrong most of the time concerning C++. I didn't compile the code -- I took the function as-is from the original message. Anyway, the main point is that an answer was made, which is far more than what you did in this thread.
You use the term "frequently", but it is very infrequent. Exactly what is your point with the above anyway? You never attempted to answer the original question -- why add the editorial comments (regardless of how untrue they are)?
You must still be hurting that QSort() was a failure. Go take your childish vendetta somewhere else.
Regards,
Paul McKenzie
Last edited by Paul McKenzie; August 27th, 2002 at 01:52 AM.
-
August 27th, 2002, 03:26 AM
#10
Originally posted by Paul McKenzie
All this coming from someone who is factually wrong most of the time concerning C++. I didn't compile the code -- I took the function as-is from the original message. Anyway, the main point is that an answer was made, which is far more than what you did in this thread.
You use the term "frequently", but it is very infrequent. Exactly what is your point with the above anyway? You never attempted to answer the original question -- why add the editorial comments (regardless of how untrue they are)?
You must still be hurting that QSort() was a failure. Go take your childish vendetta somewhere else.
Would it end the argument if I say that it is my mistake? Paul just made a copy of my function in the original post for his answer. 
In my original code I pass a const reference to pure virtual object but when I wrote the question, I did it without paying attention to it. It was just the principle of getting an object of unknown sub type that I was expecting, and I got an answer for that, thanks to Paul. 
Anthony, I'd rather have you tell me if Paul answer is incorrect than fighting about who makes typo and who is usually wrong or not...
Elrond
A chess genius is a human being who focuses vast, little-understood mental gifts and labors on an ultimately trivial human enterprise.
-- George Steiner
-
August 27th, 2002, 06:45 AM
#11
AnthonyMai,
I find your reply very amusing. This coming from the guy who posted:
Funny that There's never been an maintainability issue with my code. I just write once, get it work frawlessly, and my code are usually left un-touched for months or years. Because it just works and there is no need for any bug fix, nor there is any for for performance improvement.
and then posts some buggy qsort code.
Regards,
John Flegert
-
August 27th, 2002, 03:11 PM
#12
Now there are people who is starting to spreading rumors that my Qsort() does not work.
The fact is it works on all combinations of compilers and systems I tested it on. And no one reported a different result on those systems and compilers. The only thing that I see so far is a suspected problem in a rare case where both virtual inheritance and Portland compiler was used. I said suspected because this was reported by one user and is never verified or confirmed by some one else.
So first there is a doubt whether the claim was true or false, or maybe it is simply something made up by some one. Second, assume it is ture, it could be a bug on Portland compiler itself. Without some one getting deep into it and see what's going on, no body can say for certainty exactly what is at fault.
Since it is an isolated result only on Portland compiler, and only when virtual inheritance is used, I do not consider that a problem with my Qsort() function.
-
August 27th, 2002, 03:21 PM
#13
Hello Anthony,
If you are refering to my reply, I never said your qsort didn't work. You posted the following:
The corrected version of Qsort
Looks like I was copying the original Qsort from some where which contains a bug. But even that doesn't explain why it doesn't work on Paul's machine. Because I compiled the same thing and it works, for both debug and release.
...
Regards,
John Flegert
-
August 27th, 2002, 09:30 PM
#14
Previously posted by AnthonyMai
The only thing that I see so far is a suspected problem
in a rare case where both virtual inheritance and Portland
compiler was used. I said suspected because this was reported
by one user and is never verified or confirmed by some one else.
So first there is a doubt whether the claim was true or false,
or maybe it is simply something made up by some one.
Before accusing me of "making something up", please verify the
accuracy yourself. It is very easy to do. Just purchase the
compiler and test it yourself. You will see my statements
were 100 percent accurate and true. That would be the professional,
(not to mention ethical) thing to do.
In the "People who live in glass houses" department :
Previously posted by Anthony Mai (this is the EXACT and COMPLETE post)
Paul asked: "try to memcpy a std::string into another. See what you'll get".
I tried already. It is your turn to try it, Paul. You will get exactly the
same result just as if you do a
Code:
std::string str1, str2;
str2 = "Just try it";
str2 = str1;
// Had you done memcpy(&str2, &str1, sizeof(str2));
// It will be the same.
I know this is a C++ forum. But whenever you say something doesn't work
in certain ways in C, and I know you are wrong. I have to stand out and
point out the obvious.
When you say you can't memcpy std::string, I have to show you that
you CAN, without an error. That does NOT mean I promote such usage.
As I showed later in that thread, the memcpy() does NOT produce
"exactly the same result", and was obviously not tested as
claimed by the poster.
For those who still have the Qsort() code and the testing routines
from the previous threads, try sorting 1 million doubles using the
following initialization with both std:sort() and Qsort().
Code:
typedef vector<double> V;
typedef vector<double>::iterator IT;
void randomise_vector(V& v)
{
double factor = 3.14159;
if (v.size() > 0) factor /= v.size();
int c = 0;
for (IT i = v.begin(); i != v.end(); ++i)
{
*i = sin(c*factor);
c++;
}
}
And don't bother with another correction to Qsort().
Shouldn't I get paid for finding these obvious problems
with Qsort() ?
-
August 28th, 2002, 01:26 AM
#15
Philip:
Do NOT try to dispute the fact that memcpy() on a std::string produce the same result as an ssignment operator!!! If you do, I really have a reason to believe that you indeed made up the Portland Compiler story. I am not going buy a copy of useless compiler just to argue with you. But here is a piece of code that any one can test in just half a minute:
Code:
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char argv[])
{
string str1, str2;
string str3 = "Hello world";
memcpy(&str1, &str3, sizeof(str1));
str2 = str3;
cout << "str1 is: " << str1 << endl;
cout << "str2 is: " << str2 << endl;
cout << "str3 is: " << str3 << endl;
if (memcmp(&str1, &str2, sizeof(str1)) == 0)
{
cout << "The result of memcpy() is the same as assignment" << endl;
}
else
{
cout << "The result of memcpy() is NOT the same as assignment" << endl;
}
return 0;
}
The output is exactly identical. Any one can verify that.
As for Qsort, I already said that in the case of a few extremely simple cases, like just a double or just an int, The simple POD cases, std::sort will be marginally bettern than Qsort, thank to compiler optimization. HOWEVER, in the case where slightly complicated objects are involved, like when it is a case with a couple of strings or vectors, Qsort will beat std::sort() big big time.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|