lundi 28 décembre 2015

Passing temporary object as a reference to an abstract to a constructor

I'm a bit rusty on my C++ and have run into a bit of a snag.

I have a class, in the example user which takes a reference to an abstract class for its constructor. Ideally, I'd like for the class to support the following syntax:

User u( Sub("") );
u.work();

I have an abstract class super with a base class called sub. The user class takes a reference to super in its constructor. At runtime, user is passed a temporary reference to sub.

When u.work() is called I get an exception - because the temporary has been deconstructed. (Oddly enough I get a different behaviour if I remove the destructors on super and sub).

Example code is below!

Is there a way to fix this problem?

I know there are lots of ways if I accept to change the signature and change the syntax at the call site, but I'd prefer to hold on to the calling signature:

User u( Sub("") );
u.work();

Example code

class Super {
public:
    Super()
    {
        std::cout << __FUNCTION__ << std::endl;
    };

    virtual ~Super()
    {
        std::cout << __FUNCTION__ << std::endl;
    }

    virtual void func() = 0;
};

class Sub : public Super
{
public:
    Sub(char* name) :
        name_(name)
    {
        std::cout << __FUNCTION__ << std::endl;
    };

    virtual ~Sub()
    {
        std::cout << __FUNCTION__ << std::endl;
    }

    virtual void func()
    {
        std::cout << __FUNCTION__ << std::endl;
    }

    char* name_;
};

class User
{
public:
    User(Super& s) :
        super_(s)
    {
        std::cout << __FUNCTION__ << std::endl;
    }

    ~User()
    {
        std::cout << __FUNCTION__ << std::endl;
    }

    void work()
    {
        std::cout << __FUNCTION__ << std::endl;
        super_.func();
    }

    Super& super_;
};

int main()
{
    User u( Sub("") );
    u.work();
    return 0;
}

Aucun commentaire:

Enregistrer un commentaire