Quote:Original post by solinent
Why will I get undefined behavior? I'm creating a local copy of Mesh by passing it into B. I'm only creating a Mesh once in the local static memory of the base class.
Passing arguments for constructing a Mesh, instead of passing a Mesh directly, is not a source of undefined behaviour. What is potentially a source of undefined behaviour, is the behaviour of the copy constructors, destructors and copy assignment operators of the classes involved.
When you follow the rule of three, it is trivial to verify that resources that are allocated all get deallocated exactly once and in due time. With the copy-and-swap idiom, it is also trivial to ensure that this works even in the presence of the possibility of (a) an exception thrown in a constructor and (b) self-assignment.
Quote:However, I fail to see you suggest an answer or even point out what's wrong with my program. If I've missed it, please forgive me.
He's trying to give you general advice. Very little can be pointed out about "what's wrong with your program" because you've shown very little of your program.
Quote:Compiler tolerates code that will compile. Code that compiles is seen by the compiler as correct. Since coders are human, all code is inherently incorrect. This is the source of all bugs of all time, and you telling me this does not help me, sorry.
His whole point was to remind you of these facts, actually. We all know that code is not necessarily "correct" if it compiles. The point is that by following simple guidelines (such as the rule of three), it becomes much easier to write correct code. By disregarding such rules you throw away safety for little to no gain, unless your situation is very specific (and even then it is often not worth the effort). That the compiler can't just take care of these things for you automatically is a consequence of working in a lower-level language such as C. Languages like C# and Java effectively implement these things for you behind the scenes (except that they generally use garbage collection instead of implementing destructors, and avoid copy construction by using reference semantics for objects).
Quote:In case you're being genuine and really want to help my situation, this is what I'm doing right now:
...
As you can see, this solves my problem, but breaks your "rule-of-three" because I repeat the arguments 3 times.
The rule of three has nothing to do with the repetition of arguments. It's
this concept.
Quote:I can't create/initialize a static copy of a Mesh (within B) and pass it as a constant reference to Base because Base is initialized before everything and therefore wouldn't have access.
Yes, you can. That is what the initialization list does for you: it allows you to specify the parameters used for the constructors that
initialize the bases and members of the class. When you write
B::B(args) : Base(Mesh(args))
, you say "When the B constructor is called with args, the initialization of the Base base shall use its Base::Base(const Mesh&) constructor, passing it a temporary Mesh constructed with Mesh::Mesh(args)".
The order of events is:
Mesh::Mesh(args) constructs an unnamed Mesh.
The Mesh is passed to Base::Base(const Mesh&). The initialization of the Base does whatever with this const Mesh&; likely, it copies the Mesh into a data member, implicitly using Mesh::Mesh(const Mesh&).
Base::Base(const Mesh&) returns.
The temporary Mesh is destructed with Mesh::~Mesh(). There are no longer any references to this Mesh (because they were just parameters to functions that have already exited), so there is no problem with invalid references.
The rest of the B constructor runs.
Quote:I could use a boost::shared_pointer as specified above, but I would rather not include boost in my code (creates more dependencies).
Why do you think dependencies are a problem?