-2

I want to create an instance of a struct only if certain conditions inside its constructors are met. If those conditions are not met, I want to NOT create the instance. Not sure if this is possible, and if it is not then what is the alternate way of doing it?

Class Consumer
{




struct SampleStruct
            {
                MyClass     *   m_object;

                RoutingItem()
                {
                    m_object            = NULL;
                }
                MyClass(std::string name)
                {
                        if (! ObjSetting()->GetObj(name, m_object))//this function is supposed to populate m_object, but if it fails, I dont want to create this instance
                            return; //I dont want to create this object if GetObj() returns a false             

                }
            };



std::vector<SampleStruct> m_arrSample;

void LoadSettings(std::string name)
{

SampleStruct * ptrS;

SampleStruct s(name);


//I tried following two lines but it did'nt work. SO looks like returning from struct constructor still creates the instance
ptrS = &s;
if (!ptrS)
return;

m_arrSample.push_back(s);//only insert in vector if sampleStruct was successfully created


}




}
Daniel Daranas
  • 22,454
  • 9
  • 63
  • 116
bsobaid
  • 955
  • 1
  • 16
  • 36

4 Answers4

4

would you consider throwing an exception from inside the constructor a solution? If not so, then it is not possible. The alternative is to use a factory method which checks for the conditions and decides if an object needs to be created.

Here is a naive example of this second solution:

struct A{
};

A* factoryPtr(bool build){
    if(build)
        return new A;
    return nullptr;
}

A factoryRef(bool build){
    if(not build)
        throw 0;
    return A();
}
Stefano Falasca
  • 8,837
  • 2
  • 18
  • 24
1

I think you can define a create function to construct the instance,

test* createInstance(string name)
    {
        if(conditon )
            return new test();
        else
            return nullptr;
    }
minicaptain
  • 1,196
  • 9
  • 16
  • can you add more details such as the access modified of the struct, acces modifier of the constructor. Is it static? how to call? – bsobaid Jul 25 '13 at 15:11
1

Don't do it.

Find an alternative design. A constructor is meant to construct the object, not to decide if it constructs it or not.

Don't try to program against the rules of a language.

Daniel Daranas
  • 22,454
  • 9
  • 63
  • 116
0

Either use an exception (as Stefano says), or a factory function (as minicaptain says).

The two versions look something like this:

#include <stdexcept>
#include <memory>

struct ExceptionStyle {
    std::unique_ptr<int> m_object;

    ExceptionStyle(std::string const &name) {
        if (name == "good")
            m_object.reset( new int(42) );
        else
            throw std::runtime_error(name);
    }
};
void save(ExceptionStyle*) {} // stick it in a vector or something

class FactoryStyle {
    std::unique_ptr<int> m_object;

    FactoryStyle() : m_object(new int(42)) {}

public:
    static std::unique_ptr<FactoryStyle> create(std::string const &name) {
        std::unique_ptr<FactoryStyle> obj;
        if (name == "good")
            obj.reset( new FactoryStyle );
        return obj;
    }
};
void save(std::unique_ptr<FactoryStyle>) {} // stick it in a vector or something

can be used as follows:

void LoadSettings(std::string const &name) {

    // use the exception style
    try {
        ExceptionStyle *es = new ExceptionStyle(name);
        // if we reach here, it was created ok
        save(es);
    } catch (std::runtime_exception) {}

    // use the factory style
    std::unique_ptr<FactoryStyle> fs = FactoryStyle::create(name);
    if (fs) {
        // if we reach here, it was created ok
        save(fs);
    }
}

An exception is the only way to transfer control out of a constructor without constructing the instance. So, the alternative is to check your condition first.

Useless
  • 64,155
  • 6
  • 88
  • 132