Evan Ward
Evan Ward

Reputation: 1439

C++ - Is a pointer required to override return types - inheritance?

If I have a baseclass, Attribute, that has a method named clone which returns an Attribute, but it's subclass Direction gets an error when returning Direction.

Attribute Attribute::clone() {
    if(this->currentValue) {
        return Attribute(this->type, this->currentValue);
    } else if (!this->param.empty()) {
        return Attribute(this->type, this->param);
    } else {
        return Attribute();
    }
}

Direction Direction::clone() {
    if(this->currentValue) {
        return Direction(this->type, this->currentValue);
    } else if (!this->param.empty()) {
        return Direction(this->type, this->param);
    } else {
        return Direction();
    }
}

Although, it works when they both return a pointer to the new Attribtue. (ie return new Attribtue();, return new Direction();). Does the returned value need to be a pointer to an Attribtue?


EDIT: Here are the classes:

class Attribute {

public:
std::string param;
std::string type;
float currentValue;

Attribute(std::string type = "absolute", float value = 0);
Attribute(std::string type, std::string param);
~Attribute();
virtual Attribute clone();
};

class Direction : public Attribute{
public:
Direction(std::string type = "absolute", float value = 0);
Direction(std::string type, std::string param);
~Direction();
Direction clone();
};

Upvotes: 1

Views: 133

Answers (1)

Cheers and hth. - Alf
Cheers and hth. - Alf

Reputation: 145389

C++ supports covariant function results for raw pointers and raw references, but not for other types.

And that includes that covariant results are not supported for smart-pointers.

You can however easily work around this language limitation for smart-pointers, e.g.

class Base
{
private:
    virtual
    auto virtual_clone() const
        -> Base* 
    { return new Base( *this ); }

public:
    auto clone() const
        -> std::unique_ptr<Base>
    { return std::unique_ptr<Base>( virtual_clone() ); }
};

class Derived
    : public Base
{
private:
    auto virtual_clone() const
        -> Derived*                // Covariant is OK here. 
        override
    { return new Derived( *this ); }

public:
    auto clone() const
        -> std::unique_ptr<Derived>
    { return std::unique_ptr<Derived>( virtual_clone() ); }
};

Disclaimer: code not touched by compiler's hands.

Note that in this case of smart pointers unique_ptr<Derived> is not a derived class of unique_ptr<Base>, but offers a value conversion to the latter.


So, regarding the question title,

Is a pointer required to override return types - inheritance?

the basic answer is no, you can make things works also with non-pointers, such as smart pointer instances, but it's only meaningful for something conceptually pointer-like.

And just to repeat the opening sentence of this answer, at the language level C++ supports covariant function results for raw pointers and raw references, but not for other types.

Upvotes: 3

Related Questions