dimanche 4 octobre 2015

C++ constructor/declaration syntax: Non-clear(ie constructor() ) constructors seemingly illegal in face of internal objects requiring instantiation

Before I begin, observe the following MSVE:

class simpleClass
{
public:
    int x;
    long y;

    /*simpleClass(int xx,long yy)//example of how I want the class to work, IE it is never possible to instantiate the class in an illegal state.
    {
        x =xx;
        y=yy;
    }*/

    void initialize(int xx,long yy)//example of the real program's bypass mechanism.
    {
        x=xx;
        y=yy;
    }
};

class testclass
{
    simpleClass s;
    //simpleClass h(2,3); Not allowed in c++. Which is ok, but why is the one above, that's to say a blank instantiation, allowed?
    public:

    void unsafeStateDemonstrator()
    {
        //initialize(2,3);// this would be how I make the object actually safe.
        cout<<"X is: "<<s.x<<" Y is: "<<s.y<<endl;
        cout<<"use of x and y unsafe, but possible"<<endl;
    }
};

int main()
{
    testclass test;
    test.unsafeStateDemonstrator();
    cout<<x<<endl;

}

I can't show my actual code, but this MSVE reproduces the problem.

What happens here is that testclass is first declared in main. In testclass, there is a declaration of a simpleClass object. However, unlike java, a declaration of a object, is actually an instantiation with the use of the objects constructor with no arguments(typically the default one), trying to use an constructor with arguments (ie simpleClass s(2,3);) is strictly forbidden.

This causes havoc, as I for one, either have to provide no custom constructors of my own or provide a blank default constructor, this in turn means I have to use a secondary function to actually initialize the object properly afterwards. While this approach works, it screams of unorthodoxy, the non-optimal.

I tried reconstructing the simpleClass object afterwards by calling the custom constructor(ie s(23,44L);) inside the testclass constructor. This was met with some nonsense about "no match for call to '(simpleClass)(int , long int)'. I guess it is GCCs way of saying "you're not allowed to reconstruct objects", ofcourse I have no way of truly knowing that.

In my MSVE, this inherent unsafety is demonstrated by the "unsafestateDemonstrator"(no points for originality).

So, I guess my questions are the following:

  • How would I change this program, so I'd have a complete and safe object the moment it is constructed AND be able to this with custom constructors.

  • Is it really impossible to just declare variables in c++? It shouldn't be possible to accidentally use unfinished objects, the compiler should outright refuse to compile.

  • Why is the syntax the way it is? I mean, someObject obj; actually instantiates a object, it's not an declaration as I would've had it. In my world, it makes alot more sense if instantion would look more like java, ie someObject obj= someObject(args); or something to that effect.

I am aware that you can instantiate object with someObject obj(args). But this isn't available if you are reliant on using the object outside the owning objects constructor, ie having to declare the variable beforehand.

Aucun commentaire:

Enregistrer un commentaire