-
try to stump me on C++
Hey all,
I got a big C++ interview coming up....and I am arrogant and think I am a C++ god...so see if you can stump my knowledge of the language. I solemnly swear I won't cheat and look up the answer, and you can feel free to rip me a new one in your responses. The only requirement is that you can't include anything about particular libraries or interfaces that aren't intrinsic to C++ (stl stuff is ok). The interview won't include things like that or other trivialities which can simply be referenced. They will be asking me things like "name the 3 ways you can blah blah" or "how could the following code be improved...what is the security or memory problem...what weaknesses does it have etc"
Show me what you got! Put me in my place and make me feel like I am going into this interview a lot dumber than I think!
Thanks to all who decide to participate...I owe you one.
-
Re: try to stump me on C++
Knowledge of the syntax doesn't make you a good programmer.
-
Re: try to stump me on C++
Yes, but it is often indicative of one. The more a person know about a language's features the more time that person has probably spent using the language. And the more comprehensive that knowledge, the more likely he is a good programmer (or at least not a cheating, lazy one).
In any case, interviewers like dumb questions like:
Quote:
Why is the following bad:
Code:
class foo
{
...
foo( const foo& x )
{
*this = x;
}
...
};
(Not an actual quote.)
Hope this helps.
[edit] Oh, BTW, that is a very real, very valid question.
-
Re: try to stump me on C++
Good programming is about logic, problem solving and decomposition. Syntax is secondary. When I interview people, I don't ask any C++ or syntax questions at all. Who cares. I want to know what problems they've solved, how successful they were and how they went about it.
-
Re: try to stump me on C++
Quote:
Originally Posted by GCDEF
Good programming is about logic, problem solving and decomposition. Syntax is secondary. When I interview people, I don't ask any C++ or syntax questions at all. Who cares. I want to know what problems they've solved, how successful they were and how they went about it.
I knew someone who knew all the nuances of the Windows API. The problem is he couldn't write a real program if his life depended on it...
Regards,
Paul McKenzie
-
Re: try to stump me on C++
Quote:
Originally Posted by Paul McKenzie
I knew someone who knew all the nuances of the Windows API. The problem is he couldn't write a real program if his life depended on it...
Regards,
Paul McKenzie
Me too. Whatever new technology came out, he immersed himself in it. STL, Com, whatever it was, he knew it inside out. His knowledge of syntax and tricks is way beyond what mine will ever be. Despite his immense knowledge, his code is unmaintainable junk. I remember taking a very long time trying to explain to him how to calculate an arithmetic mean.
-
Re: try to stump me on C++
Complete agreement with all of the previous assesments. :wave: :thumb:
But this is a favorite of mine...
Code:
static int X = f();
int f() { return X; }
int main()
{
cout << X << end;
}
-
Re: try to stump me on C++
thanks for your reply duoas,
Ok without cheating....basically you never want to modify the "this" pointer, expecially this way. In fact, this could be an example of the worst case scenario use of *this. It is usurping the allocation of the class (major memory leak). It's also potentially wreaking havoc with the "new"-ing of this class, potentially forcing some kind of access violation. Lot's of negative implications with modifying *this, and should almost never be done. Alternatively, to properly copy an instance of a class, do a member-wise copy in your copy constructor, or simply leave out the copy constructor and the operator= overload and the default behavior will be do implement those functions behind the scenes. Or, if it really was one's intention to simply create a second pointer to the same exact memory space, one can just declare a pointer to that class (or it's parent if applicable), and set the pointer to the first instance's address....
That was a good question...hope I got it right...
Any more?
-
Re: try to stump me on C++
haha...good one CPUWizard....ok, you got me on that one....I knew it was a compile error, but I didn't see it clearly....once I compiled it though, it made sense....comes down to compiler choices I would think..
-
Re: try to stump me on C++
@GCDEF, Paul McKenzie
I said more likely, not absolutely. I've known my share of 'real programmers' too...
Quite simply, much of the time people doing the hiring are mid-level managers who know very little about actually good programming. If your company doesn't hire that way then you seem to be in a good place.
I would hire people the same way you do.
@CPUWizard
LOL Nice one!
@andersod2
You did, and very comprehensively too. :-)
-
Re: try to stump me on C++
"Is it at all possible to create a local function inside a function in C++? If so, how?"
"Why might you write a pure virtual destructor with inline implementation?"
-
Re: try to stump me on C++
Quote:
Originally Posted by Duoas
@andersod2
You did, and very comprehensively too. :-)
Did he? Personally I found the answer a bit vague but then so was the question. What are the data members? How is operator= implemented.
My question to andersod2 would be: What exactly do you think might happen if the only data member were an std::string or a boost smart pointer?
My answer to Duoas' question would have been that operator= should be implemented via the copy constructor, not the other way around. Using operator= in the copy constructor is either wasteful or downright catastrophic. Because the operator= will assume that the class is already fully constructed, it might try to delete a data member pointer which has not yet been initialised.
And if operator= has correctly been implemented using the copy constructor, an infinite recursion would very quickly crash the application.
-
Re: try to stump me on C++
> "Is it at all possible to create a local function inside a function in C++? If
> so, how?" "Why might you write a pure virtual destructor with inline
> implementation?"
All right! Now that's the kind of BS I'm talking about. Ok, I won't cheat.
(1) The important part is, in any case, you would never want to do that. But I'm going to go ahead and say "yes, you can do it." I'm going to say use a label, some brackets, and a jumping method of some type (be it with an inline assembly jmp or...does C++ have a goto statement? haha)....then manage the stack yourself etc. That would be the hard way. If you can use built-in syntax is something I don't even want to know, but my instincts tell me that yes you can because a function call is merely a standard set of actions that are performed according to a calling convention. If one of my employees ever tried it, I'd make them wear their underwear on their head outside in the cold.
(2) Well as with anything in C++, there's always a lot of good reasons to do something no matter how crazy it seems...and this does seem crazy at first glance, but let's just look at it according to what we know. Of course, virtual destructors are what you want just about any time you are using derivation (and definitely if you're using virtual functions). So if we extend that idea out to pure virtual, it just means that we don't want our base-class doing any destruction whatsoever. That could mean the base class was composed of no data to begin with, or for some reason we want to usurp the typical destruction order. But I think the main reason would be that somebody with no knowledge of the class in question is responsible for destroying it via a base class pointer. It would be part of a high-level architecture. The base-class pointer is all the user code would have, so it couldn't know which destructor to call. This is also a good high-performance/efficiency thing since there's no function overhead, and no multiple function calls.
Great questions! Keep 'em comin'!
-
Re: try to stump me on C++
> Did he? Personally I found the answer a bit vague...
yes, and vague usually gets the job ;)
> My question to andersod2 would be: What exactly do you think might
> happen if the only data member were an std::string or a boost smart
> pointer?
Well I think you were right in your operator= comments. My comments were based on the assumption that the operation was possible, or that you didn't dereference the "this" pointer and were just casting away the uniqueness of everything to make it a legal operation. If that were the case, then the same comments would be in effect, namely memory leak for sure, and possibly a program crash on destruction. Otherwise, like you say, I think this operation would probably not even be possible to compile/link at best, and catastrophic failure at worst. For it to work, the operator= would have to be defined without the need for any copy construction....sort of like a copy constructor :P
-
Re: try to stump me on C++
Local function:
Code:
void f()
{
struct Local
{
/* Can only be called from inside f(). */
static int average(int a, int b)
{
return (a+b)/2;
}
};
int x1 = 3;
int y1 = 5;
int x2 = 6;
int y2 = 8;
int z1 = Local::average(x1,y1);
int z2 = Local::average(x2,y2);
}
Regarding the pure virtual destructor with inline implementation.
Defining a pure virtual destructor can be useful if (for some reason) you want an abstract base class when there are no other pure virtual functions in that class (I know some would argue against doing that, but that's another matter).
The important thing to remember is that even a pure virtual destructor will always need to be defined, even though it is pure virtual, because the derived class will call it. And if it is trivial (or even empty) then it might as well be inlined.
-
Re: try to stump me on C++
Quote:
Originally Posted by Zaccheus
The important thing to remember is that even a pure virtual destructor will always need to be defined, even though it is pure virtual, because the derived class will call it. And if it is trivial (or even empty) then it might as well be inlined.
Depends on the definition of "call". :D
Yes the derived class will "invoke" it, but when declared as inline (and the compiler infact in-lines ir) there will no "call" (transfer of control to antherseries of instructions and back, invalidating the processor pipeline). The invocation will simply be optimized out out existance.
Mr Schroedinger is still looking for his cat... ;) ;)
-
Re: try to stump me on C++
Yeah that was the whole point, getting rid of the invocation by making it inline. :wave:
Quote:
Originally Posted by andersod2
My comments were based on the assumption that the operation was possible
as were mine :)
Quote:
Originally Posted by andersod2
, or that you didn't dereference the "this" pointer
but the code does do that.
Quote:
Originally Posted by andersod2
and were just casting away the uniqueness of everything to make it a legal operation.
Hmm, I don't see how casting comes into it.
Quote:
Originally Posted by andersod2
Otherwise, like you say, I think this operation would probably not even be possible to compile/link at best
why not?
Quote:
Originally Posted by andersod2
, and catastrophic failure at worst.
Which takes us back to my question: "What exactly do you think might happen if the only data member were an std::string or a boost smart pointer?"
Code:
class foo
{
std::string data;
public:
foo( const std::string& str )
: data(str)
{
}
foo( const foo& x )
{
operator=(x); // same as: *this = x;
}
foo& operator=(const foo& other)
{
if(&other != this)
{
data = other.data;
}
return *this;
}
};
Ignoring the fact that the copy constructor & assignment operator are unnecessary in this simple example.
-
Re: try to stump me on C++
Quote:
Originally Posted by Zaccheus
as were mine :)
but the code does do that.
Hmm, I don't see how casting comes into it.
The original question was, as you say, ambiguous, so it was difficult to determine directly from the code what was intended. So I did not so much look exactly at the code as I did what the poster's point was. I believe the question was intended to reveal a memory leak, though the code does not *exactly* prove this...it's just implied due to lack of other info. The more exact answer would have been your comments, but I didn't get into that.
Quote:
Originally Posted by Zaccheus
why not?
Well, if the operator equals also had a copy construction in it, as we fear, then the best case scenario is that the compiler says "you did some circular stuff" or whatever and fails.
Quote:
Originally Posted by Zaccheus
Which takes us back to my question: "What exactly do you think might happen if the only data member were an std::string or a boost smart pointer?"
Hmm...at first glance I'm not seeing it, other than the same problem as before. I would need to double check the copy constructors and assignment operators of std::string, but I'm guessing that isn't the problem.
-
Re: try to stump me on C++
Quote:
Originally Posted by andersod2
Hmm...at first glance I'm not seeing it, other than the same problem as before. I would need to double check the copy constructors and assignment operators of std::string, but I'm guessing that isn't the problem.
If you need a hint, the example Zaccheus gave will compile and run fine. The answer you're looking for is more of a stylistic guideline (or "moral") than a specific compile- or run-time problem. Mostly it involves the difference between initialization and assignment, as well as what it means for an object to be "fully constructed".
Can you at least explain the difference between these two pieces of code, and the importance of that distinction?
Code:
// A
int a = 0;
// B
int b;
b = 0;
-
Re: try to stump me on C++
Another hint is "Exception Safety".
Try to write a (significant) assignment operator that is guarenteed to not have any memory leaks or any partially initialized objects if an exception is thrown at any sequence point.
-
Re: try to stump me on C++
Quote:
Originally Posted by Hermit
The answer you're looking for is more of a stylistic guideline (or "moral")
Yes, I'm getting the moral part of it, which I think was kind of implied in what Zaccheus was saying before about the problem with the original code. You just don't want your copy constructor and your operator= being dependant on one another. Otherwise the code you posted could produce drastically different results since the first one was copy constructed and the second one was just constructed then assigned with operator=....so but my confusion is perhaps semantic whereas Zacc is saying "what if there was a single member of std::string or a boost smart pointer" which makes it sound as though the problem comes down to having a single member or a specific kind of member. If that's not it, and it's just what you were saying, then, I guess "oh, I see" :P C++ makes it easy to invent new problems that don't exist :)
-
Re: try to stump me on C++
OK, one more hint...
IF you have a class whos members are either POD, or classes which properly implement their respective copy constructors....
How much code do you have to write ti implement a copy constructor?
Between the last two hints, that should be sufficient...
IF not, please provide your physical location, and I will send someone to do a "Mark Harmon" (reference to TV show NCIS) on you. :D :wave: ;)
-
Re: try to stump me on C++
Quote:
Originally Posted by TheCPUWizard
IF not, please provide your physical location, and I will send someone to do a "Mark Harmon" (reference to TV show NCIS) on you. :D :wave: ;)
Better a 'Mark Harmon' than a 'Tanya Harding' any day of the week.
-
Re: try to stump me on C++
Quote:
Originally Posted by TheCPUWizard
Another hint is "Exception Safety".
That's a good point, and a subtle one at that. It is possible to write an exception safe assignment operator without invoking the copy constructor (which would invoke the assignment operator, and so on ad infinitum), even using the no-throw swap method... but it wouldn't be pretty. Basically you'd need a way of effectively creating a copy without using the copy constructor.
-
Re: try to stump me on C++
Quote:
Originally Posted by Hermit
That's a good point, and a subtle one at that. It is possible to write an exception safe assignment operator without invoking the copy constructor (which would invoke the assignment operator, and so on ad infinitum), even using the no-throw swap method... but it wouldn't be pretty. Basically you'd need a way of effectively creating a copy without using the copy constructor.
1) Unfortunately many people do not consider excptions as they are writing each line of code.. :mad: :sick:
2) There is a big difference between "possible" and "practical", which i think we agree on... :wave:
-
Re: try to stump me on C++
> Another hint is "Exception Safety".
True. You would need a well-defined constructor to begin with and a routine that equates to a destructor called from your catch block.
> IF you have a class whos members are either POD, or classes which
> properly implement their respective copy constructors....
> How much code do you have to write ti implement a copy constructor?
I think there is some confusion here as to whether you and Zacc are referring to the same thing. I alluded to the answer to this question earlier when saying that the copy constructor will be implemented automatically. What I didn't say was that the implementation will include a member-wise copy (with operator=), which, under the conditions you gave, should work out well, requiring no real code to be written. Like I say I don't recall the specifics of the operator= for strings and what not. At this point I don't even know what the question is anymore, so go ahead and send Clay Aiken over to sing me a song. I'm certain I'll end up saying "that's what I said, right?"
-
Re: try to stump me on C++
Quote:
Originally Posted by andersod2
Yes, I'm getting the moral part of it, which I think was kind of implied in what Zaccheus was saying before about the problem with the original code. You just don't want your copy constructor and your operator= being dependant on one another.
Just to be clear, I was saying that the operator= SHOULD be dependent on the copy constructor, but for very practical reasons - the "Exception Safety" which TheCPUWizard mentioned.
Quote:
Originally Posted by andersod2
....so but my confusion is perhaps semantic whereas Zacc is saying "what if there was a single member of std::string or a boost smart pointer" which makes it sound as though the problem comes down to having a single member or a specific kind of member. If that's not it, and it's just what you were saying, then, I guess "oh, I see" :P C++ makes it easy to invent new problems that don't exist :)
I wasn't saying there would be a problem, I was asking what you thought would actually happen. Basically I'm trying to understand what you mean by your answer:
Quote:
Originally Posted by andersod2
basically you never want to modify the "this" pointer, expecially this way. In fact, this could be an example of the worst case scenario use of *this. It is usurping the allocation of the class (major memory leak). It's also potentially wreaking havoc with the "new"-ing of this class, potentially forcing some kind of access violation. Lot's of negative implications with modifying *this, and should almost never be done"
Now my comment on the full class I posted would be this: It will compile, link and run just fine, because std::string default constructs itself to a valid object. However it is not-optimal for the data members to first construct themselves and then be overwritten immediately afterwards. On the other hand, if one of the data members is not of a type which default constructs to a valid object (like a raw pointer which will by default contain garbage) then the program will very likely crash.
-
Re: try to stump me on C++
Quote:
Originally Posted by Zaccheus
Just to be clear, I was saying that the operator= SHOULD be dependent on the copy constructor, but for very practical reasons - the "Exception Safety" which TheCPUWizard mentioned.
i disagree, first of all it breaks reservation of memory in allocators, second of all this is redundent code. also where is the logic? the same that it would not be logic to call operator= in the copy constructor for many reasons. This all for a "state" of an object, does it really "beak" the instance? as far as i know exceptions have nothing todo with objects, and as far as i know there isnt really a object or instance.
same goes for protecting the copy assignment for assigning to itself, cus first of all there should not be a problem with assigning to itself, i agree there might be a rare case that a class manages it so it cannot assign to itself. second of all its the programmers fault for assigning to itself. third of all the chance that a instance actually assigns to itself its very rare. It only wastes cpu cycles. And trust me when your doing lots of copying these cpu cycles become precious. and dont tell me to goto C then or ASM cause that is bull ****.
also dont tell me these cpu cycles are nothing in modern computers cus if your programming for a 1 watt processor for a laptop this is a diffrenrt story
-
Re: try to stump me on C++
Mitsukai, I was talking about the following technique:
Code:
MyClass& MyClass::operator=(const MyClass& other)
{
// use copy constructor to create a copy.
// If an exception happens, then 'this will remain unchanged.
MyClass temp(other);
// Use a member function called swap to exchange the internal representations of 'this' and temp, just like std::vector<T>::swap does.
swap(temp); // Cannot throw exceptions!
return *this;
}
-
Re: try to stump me on C++
so was i
Code:
MyClass& MyClass::operator=(MyClass temp)
{
Swap(temp);
return *this;
}
-
Re: try to stump me on C++
Quote:
Originally Posted by Mitsukai
so was i
Code:
MyClass& MyClass::operator=(MyClass temp)
{
Swap(temp);
return *this;
}
Then I don't understand your objections.
-
Re: try to stump me on C++
its bad design...
cause your constructing a whole object on the stack and then wasting another cpu cycles with the swap method... while all u have todo is call a common private function.
-
Re: try to stump me on C++
I don't see the swap function as a significant waste. Creating the temp on the stack and swapping the internal pointers is almost the same expense as using temporary pointers in the assignment operator function.
How would you write a typical assignment operator then?
-
Re: try to stump me on C++
Quote:
Originally Posted by Zaccheus
I don't see the swap function as a significant waste. Creating the temp on the stack and swapping the internal pointers is almost the same expense as using temporary pointers in the assignment operator function.
first, do you have proof that this is actually true. cause an object is alot heavier than a temp pointer.
and did i mention yet in allocators this breaks the reservation of memory?
-
Re: try to stump me on C++
Quote:
Originally Posted by Mitsukai
its bad design...
cause your constructing a whole object on the stack and then wasting another cpu cycles with the swap method... while all u have todo is call a common private function.
No that (Zaccheus post) is a very good design, and the one most recommended for high reliability situations.
The only time to avoid it is if you havwe measured performance and determined that the small differential cost has a significant impact on your documented performance requirements.
No matter where an exception occurs you can never have a corrupted or partial object. Either the assignment will complete 100% or the state of the (externally visible) object will not be impacted. This is guaranteed by design.
Even if you manage to write a "typical" assignment operator that is 100% exception safe, then you still have to develop tests to prove this (and maintain both the code and the tests for the entire lifecycle of the project).
Testing and proving exception safety (in the general case...) is a notoriously hard (and unbelievably tedious) thing to do.
-
Re: try to stump me on C++
i agree with most of your points but i still stand by my point, and it will probally never change unless i get paid. I still think it as a bad work around. But thats just my point of view.
-
Re: try to stump me on C++
I would really like to see an exception safe operator= which is a lot faster than the one I showed.
Quote:
Originally Posted by Mitsukai
first, do you have proof that this is actually true. cause an object is alot heavier than a temp pointer.
I think it is self evident that an object it is NOT a lot heavier than its individual data members.
Quote:
Originally Posted by Mitsukai
and did i mention yet in allocators this breaks the reservation of memory?
How, exactly?
-
Re: try to stump me on C++
Quote:
Originally Posted by Zaccheus
I think it is self evident that it is NOT a lot heavier than equivalent temp pointers.
Prove it to me? and what makes you say that this "lil" bit is not alot on 1watt laptop processors? who are you to say this "lil" overhead is actually not alot?
Quote:
Originally Posted by Zaccheus
How, exactly?
cause the whole point of it is to "Adept" to the usage of the class, the more is added the more memory it will reserve. If you create a complete new object all this reserved memory is gone. Also the whole point of the memory reservation is to prevent it from allocating memory every time it needs more space. And then when adding again which is must likely to happen in large applications it has to allocate again all that space. This is for containers ofcourse.
-
Re: try to stump me on C++
Quote:
Originally Posted by Zaccheus
I think it is self evident that an object it is NOT a lot heavier than its individual data members.
one ptr on the stack vs a whole object? there is no need to have tmp vars at all in most cases, so if the obj has 10 var members its even more clear waste of stack and cpu
-
Re: try to stump me on C++
Please show me the assignment operator implementation you prefer and then we can compare. :)
-
Re: try to stump me on C++
Quote:
Originally Posted by Mitsukai
one ptr on the stack vs a whole object? there is no need to have tmp vars at all in most cases, so if the obj has 10 var members its even more clear waste of stack and cpu
Actually adjusting the stack pointer by <32K (signed 16 bit offset) takes FEWER clock cycles than pushing one 32 bit value. So that part of your post is WRONG.
Unless the copy constructor is invoked in the call stack of the maximum stack depth your program ever achieves, then does not waste a single byte of memory. This maximum stack depth will (typically) occur at exactly one point in your program, and if you are working on small systems (embedded, tiny mobile, etc), then you should know exactly where and when this is.
The pre-allocation your are talking about is spefically for the freestore (used with new/delete), this is because there is management overhead of finding the "best" free block, and for collapsing free blocks at the time of delete. It has nothing to do with stack variables.
-
Re: try to stump me on C++
Here's a concrete example:
Code:
#include <cstring>
#include <algorithm>
class Buffer
{
unsigned char* data;
size_t length;
public:
Buffer(const unsigned char* buf, size_t len)
: data(new unsigned char[len]),
length(len)
{
std::memcpy(data, buf, length);
}
Buffer(const Buffer& other)
: data(new unsigned char[other.length]),
length(other.length)
{
std::memcpy(data, other.data, other.length);
}
~Buffer()
{
delete [] data;
}
Buffer& operator=(const Buffer& other)
{
Buffer temp(other);
swap(temp);
return *this;
}
void swap(Buffer& other)
{
std::swap(data, other.data);
std::swap(length, other.length);
}
};
-
Re: try to stump me on C++
Quote:
Originally Posted by andersod2
Ok without cheating....basically you never want to modify the "this" pointer, expecially this way.
Who is modifying the "this" pointer? Modifying this pointer is a compilation error and the code above doesn't do that.
Quote:
Originally Posted by andersod2
In fact, this could be an example of the worst case scenario use of *this.
Meaningless. As for use of the dereferencing of the this pointer, it is perfectly valid.
Quote:
Originally Posted by andersod2
It is usurping the allocation of the class (major memory leak).
I don't see a leak forget about it being a major one.
Quote:
Originally Posted by andersod2
It's also potentially wreaking havoc with the "new"-ing of this class, potentially forcing some kind of access violation.
No new-ing, and no access violation. What are you talking about?
Quote:
Originally Posted by andersod2
Lot's of negative implications with modifying *this, and should almost never be done.
What? What negative implications? You can modify the object pointed to by the this pointer. Why should it almost never be done?
Quote:
Originally Posted by andersod2
Alternatively, to properly copy an instance of a class, do a member-wise copy in your copy constructor,
As I see it, I do see a member-wise copy even though the code is not an example of *real* code (in practice). What are you talking about?
Quote:
Originally Posted by andersod2
or simply leave out the copy constructor and the operator= overload and the default behavior will be do implement those functions behind the scenes.
To come to a conclusion on that, one needs to know what those (...) stand for in the original snippet. So, a counter-question for clarifications from my side. Should avoid reaching conclusions so early.
Quote:
Originally Posted by andersod2
Or, if it really was one's intention to simply create a second pointer to the same exact memory space, one can just declare a pointer to that class (or it's parent if applicable), and set the pointer to the first instance's address....
What? I cannot make out a single sensible meaning out of this.
Quote:
Originally Posted by andersod2
That was a good question...hope I got it right...
Horrible, if you frankly ask me. But there's always hope. :)
-
Re: try to stump me on C++
Quote:
Originally Posted by Duoas
@andersod2
You did, and very comprehensively too. :-)
Yeah, right. :) It is a bit unfortunate that you say that after seeing that the question came from you.
-
Re: try to stump me on C++
Quote:
Originally Posted by Zaccheus
My answer to Duoas' question would have been that operator= should be implemented via the copy constructor, not the other way around. Using operator= in the copy constructor is either wasteful or downright catastrophic.
Yes. Fully agree. Writing exception safe assignment operators is one advantage you get that way. But I think it is not catastrophic even though there's not enough code to come to a conclusion but it would not be very hard to imagine that the code works except that there's a difference of initialization vs assignment as suggested by Hermit somewhere above I think. Apart from that, I don't see a problem.
Quote:
Originally Posted by Zaccheus
Because the operator= will assume that the class is already fully constructed, it might try to delete a data member pointer which has not yet been initialised.
That would be the problem with the "other" constructors which left uninitialized pointers. (EDIT: Sorry, on a second thought, yes, it can be a problem).
Quote:
Originally Posted by Zaccheus
And if operator= has correctly been implemented using the copy constructor, an infinite recursion would very quickly crash the application.
In that case, a simple advice would be "don't work for such a firm whose developers don't know how to write copy constructors and assignment operators". :)
-
Re: try to stump me on C++
Exterminator, look at my example class here:
http://www.codeguru.com/forum/showpo...3&postcount=42
If the assignment operator in that example were simply ...
Code:
Buffer(const Buffer& other)
{
*this = other;
}
... then the application would almost certainly crash when the assignment operator tries to free the existing data in temp's destructor, agreed?
EDIT:
Ah, I see your edit, looks like we are agreed. :)
-
Re: try to stump me on C++
Quote:
Originally Posted by Zaccheus
Exterminator, look at my example class here:
http://www.codeguru.com/forum/showpo...3&postcount=42
If the assignment operator in that example were simply ...
Code:
Buffer(const Buffer& other)
{
*this = other;
}
... then the application would almost certainly crash when the assignment operator tries to free the existing data in temp's destructor, agreed?
EDIT:
Ah, I see your edit, looks like we are agreed. :)
Yes, agreed. I am not thinking of as far as the destructor of temp or otherwise. It just slipped my mind that POD types (our pointer member here, considering it is not a smart one but the old, dumb, naked one :) ) remain uninitialized in constructor body if not initialized in the initializer list. And in that case, it would be impossible to predict if a pointer member points to something meaningful or not and hence any free-up on it would be an UB leading to one possibility - a crash. So, we are okay on this one. :)
-
Re: try to stump me on C++
Quote:
Originally Posted by andersod2
haha...good one CPUWizard....ok, you got me on that one....I knew it was a compile error, but I didn't see it clearly....once I compiled it though, it made sense....comes down to compiler choices I would think..
Assuming you fix compilation errors related to non inclusion of <iostream> and that you forward declare the function before its use and you qualify namespaces, the code doesn't complain. I am not very sure on this one, but I think it is ill-formed (or atleast that the initialization is meaningless and X has unpredictable value) as it tries using X to initialize X before X is initialized. Comeau compiles the code fine and Visual Studio 2005 prints out "0" with all build configurations and optimization levels. So, I am really unsure what is a definitive answer and I am quite stressed out to look into the standards. Sorry.
-
Re: try to stump me on C++
Quote:
Originally Posted by andersod2
Hey all,
I got a big C++ interview coming up....and I am arrogant and think I am a C++ god...so see if you can stump my knowledge of the language. I solemnly swear I won't cheat and look up the answer, and you can feel free to rip me a new one in your responses. The only requirement is that you can't include anything about particular libraries or interfaces that aren't intrinsic to C++ (stl stuff is ok). The interview won't include things like that or other trivialities which can simply be referenced. They will be asking me things like "name the 3 ways you can blah blah" or "how could the following code be improved...what is the security or memory problem...what weaknesses does it have etc"
Show me what you got! Put me in my place and make me feel like I am going into this interview a lot dumber than I think!
Thanks to all who decide to participate...I owe you one.
Thought this topic was about you ?? now were have you gone ?? lol; no traces of your messages again.
I'm new to C++ (still struggling with it for 2months now :D) what are POD types?? and what is the big deal about this copy constructors??
-
Re: try to stump me on C++
Quote:
Originally Posted by exterminator
Assuming you fix compilation errors related to non inclusion of <iostream> and that you forward declare the function before its use and you qualify namespaces, the code doesn't complain. I am not very sure on this one, but I think it is ill-formed (or atleast that the initialization is meaningless and X has unpredictable value) as it tries using X to initialize X before X is initialized. Comeau compiles the code fine and Visual Studio 2005 prints out "0" with all build configurations and optimization levels. So, I am really unsure what is a definitive answer and I am quite stressed out to look into the standards. Sorry.
Well I did type the code in raw...thanks for taking the time to get past that... :wave: :thumb:
It actually IS very well defined behavior, although one that some (pre-2003) compilers did not conform to the standard.
disclaimer: I would NOT accept this in any real world design, for two reasons. The defined behaviour is useless, and it takes a significant amount of time to find out that it is useless...