0

I am relatively new to the OO side of C++, so please forgive this question, which I imagine is relatively straight-forward;

I have some code, loosely like this

SuperClass* super;

if (useSub1())
{
    SubClass1 sub1 (s);

    super = &sub1;
}
else if (useSub2())
{
    SubClass2 sub2 (s);

    super = &sub2;
}

super.someMethod();

It should be noted, that the point here is that the Construction of 'sub' is dependent upon the result of the call to someFunction(). Furthermore, there will be multiple if (...) { } constructs like above, each creating a different Object based on a different SubClass of SuperClass, based on some condition.

In summary then SuperClass has a number of Sub-classes, and I want to create the appropriate object type based on an if condition, then use the 'super' object to manipulate them.

Here is my question, I think by doing what I have sub1 (or sub2 for that matter) will go out of scope, so does this leave me with a pointer to nothing?

I hope it is reasonably clear what I am trying to do, I am just not sure how to code it correctly. Any help or advice is gratefully received.

Thanks in anticipation

1
  • 1
    Yeah, it leaves you with a bad pointer. It'll be undefined behavior. If you want memory that outlives the scope it was created in, you'll have to use new. Commented Mar 26, 2014 at 15:52

4 Answers 4

2

Read about creational patterns, according to the information in your question: factory or factory method might suit your needs.

That design patterns allows to create objects dynamically in the heap, and you can operate with created object using pointer to a base class.

To prevent memory leaks and properly handle resources I suggest you to use smart pointers: std::unique_ptr<Type> or boost::shared_ptr<Type>
if you are going to use std::auto_ptr don't use it with containers

Sign up to request clarification or add additional context in comments.

5 Comments

Dont use std::auto_ptr, use std::unique_ptr instead.
@const_ref Oh, yes sure thank you. In any case it is useful to get acquainted with smart pointers concept as a good tool for resources management
@Daniel Daranas as far as I know auto_ptr allows copying in container that could lead to errors in that case unique_ptr is more robust (because when you copy auto_ptr/ unique ownership is transfered and you can be left with dangling pointers if you use auto_ptr with containers like vector for example)
auto_ptr has a weird copying behavior: a = b steals b's contents and handles them to a. That might be not what the user intended to do.
Out of curiosity... how would be different a factory from packaging the code in the original question as a (factory) class?
0

As @Ben indicates: use new

SuperClass* super;

if (useSub1()) {
    super = new SubClass1(s);
}
else if (useSub2()) {
    super =new SubClass2(s)
}

super->someMethod();

5 Comments

what if both useSub1() and useSub2() return false
er... yes, sorry. I was just following the same structure as in the original question.
Thanks for your answer, it does of course work perfectly. I have always resisted the use of new, as this requires some housekeeping to delete it. Though in this case, this seems to be the best approach. Further to the comments about there being no 'catch all' if the conditions in the if's fail. This is only loosely what I wanted to do, and I accept that this needs addressing in the actual code. Thanks again
If you're concerned about the lifecycle of the allocated memory, look into using smart pointers (as it has been suggested in other answers)
Smart Pointers might indeed be another way. I have implemented your initial suggestion of using new for now, and that has moved me along. Thanks for your time.
0

Yes, sub1 and sub2 object dtors will be invoked as they go out of scope, and the 'super' pointer will be left pointing to an object in stack of indeterminate state. In some cases, it may still be in valid memory regions, hence not resulting in a segment violation, leading to a subtle bug.

It also looks like you need something like an 'Abstract Factory' design pattern:

http://en.wikipedia.org/wiki/Abstract_factory_pattern

Comments

0

You can use a factory method:

std::unique_ptr<SuperClass> create(const std::string& name)
{
    if (name == "Sub1")
        return std::unique_ptr<SubClass1>{new SubClass1};

    if (name == "Sub2")
        return std::unique_ptr<SubClass2>{new SubClass2};

    throw std::runtime_error;
}

Here I've used an std::string to choose the type of the object to create, but it could be an enum instead.

Note that std::unique_ptr manages the lifetime of the object by itself, so there is no need to delete anything.

void foo()
{
    auto object = create("SubClass1");
    object->bar();
} <-- object is deleted automatically

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.