简体   繁体   中英

Can I call the subclass constructor from my superclass?

I want to know if I can return a subclass object through an overloaded operator from my superclass.

#include <stdio.h>
#include <iostream>
using namespace std;

struct AndSpecification;

struct Specification{
    virtual bool is_satisfied(int i) = 0;  



    AndSpecification operator&& (Specification & other){
        return AndSpecification(*this, other);
    }

};


struct Specification1 : Specification{
    int k;
    Specification1(int k) : k(k){}

    bool is_satisfied(int i){
        if (i > k)
            return true;
        return false;
    }

};

struct Specification2 : Specification{
    int k;
    Specification2(int k) : k(k){}

    bool is_satisfied(int i){
        if (i < k)
            return true;
        return false;
    }
};

struct AndSpecification : Specification{
    Specification& first;
    Specification& second;

    AndSpecification(Specification& first, Specification& second) : first(first), second(second){}

    bool is_satisfied(int i) override{
        return first.is_satisfied(i) && second.is_satisfied(i);
    }
};

I think that the result is that I can't use the constructor of my subclass because it is not yet defined. The error messages are:

main.cpp: In member function 'AndSpecification Specification::operator&&(Specification&)':

main.cpp:20:56: error: return type 'struct AndSpecification' is incomplete AndSpecification operator&& (Specification & other){ ^

main.cpp:21:45: error: invalid use of incomplete type 'struct AndSpecification' return AndSpecification(*this, other);

Your incomplete forward class declaration cannot be used in this manner until the class is fully defined. Incomplete (forward) class declaration can be used in certain cases, but this is not one of them.

A C++ compiler reads the source in order, from start to finish. When it sees your operator, it has no idea what this mysterious class is, that it's returning. It has not been defined yet. It only gets defined later, in the header/source file.

You need to declare the class method, and then define it only after the class it's returning is fully defined:

// ...

struct Specification{
    virtual bool is_satisfied(int i) = 0;  



    AndSpecification operator&& (Specification & other);

};

// After AndSpecification is declared, later:

inline AndSpecification Specification::operator&& (Specification & other){
    return AndSpecification(*this, other);
}

As an alternative to inline , put the definition of the operator method into one of the translation units.

Whenever the compiler must know the size of a type, it must be defined. A declaration is not enough for constructing a type.

In your case, the simple fix is to make operator&& a free function and move it to the bottom:

AndSpecification operator&& (Specification & left, Specification & right){
        return AndSpecification(left, r)ight;
    }

In my opinion, free binary operators are better than member functions.

You've implemented an inline function definition before completing the definition of one of the classes you're using in the function. The compiler knows there's a struct AndSpecification but it doesn't know that the particular constructor you're using exists. Declare your method in the class but don't define it until after the definition of AndSpecification .

struct Specification{
    virtual bool is_satisfied(int i) = 0;  
    AndSpecification operator&& (Specification & other);
};

struct AndSpecification : Specification { ... }

inline Specification::operator&& (Specification & other) {
    return AndSpecification(*this, other);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM