在C+中实现接口类的创建功能+; 阅读有效的C++,项目31描述了两种方法,通过使客户端使用只提供一个接口的函数来最小化重新编译时间。此类将这些函数调用引用到执行实际工作的其他类

在C+中实现接口类的创建功能+; 阅读有效的C++,项目31描述了两种方法,通过使客户端使用只提供一个接口的函数来最小化重新编译时间。此类将这些函数调用引用到执行实际工作的其他类,c++,class,interface,C++,Class,Interface,描述的第一个方法是Handle类,它使用pImpl习惯用法将函数调用转发到实现类,实现类包含它所做的一切的实现。Handle类有一个指向该类型实例化对象的指针,其函数调用该对象上的相应函数并返回它们的值 我遇到的问题是第二个问题,在第二个问题中,这是使用带有所有纯虚拟函数的基类实现的。在这个方法中,基类定义了允许调用的函数,但它们都被声明为纯虚函数,因此派生类才是真正实现它们的类。客户端具有指向派生类对象的基类指针或引用,并调用这些函数,这些函数映射到派生类的实现函数。这本书描述了让基类具有一个

描述的第一个方法是Handle类,它使用pImpl习惯用法将函数调用转发到实现类,实现类包含它所做的一切的实现。Handle类有一个指向该类型实例化对象的指针,其函数调用该对象上的相应函数并返回它们的值

我遇到的问题是第二个问题,在第二个问题中,这是使用带有所有纯虚拟函数的基类实现的。在这个方法中,基类定义了允许调用的函数,但它们都被声明为纯虚函数,因此派生类才是真正实现它们的类。客户端具有指向派生类对象的基类指针或引用,并调用这些函数,这些函数映射到派生类的实现函数。这本书描述了让基类具有一个工厂函数,该函数返回指向派生类的指针。根据本书的示例,如果Person是基类,RealPerson是派生类,那么客户端应该能够创建如下对象:

std::string name;
Date dateOfBirth;
Address address;

//create an object supporting the Person interface
std::tr1::shared_ptr<Person> pp(Person::create(name, dateOfBirth, address);
g++编译器在
RationalBase*ptr=new-Rational(上,下)一行给了我错误
无效使用不完整类型'struct-Rational'
创建
函数中


在谷歌上搜索这个错误,我发现这可以解释为什么这样做的原因是只允许对前向声明的类执行这么多操作,而创建它们的新实例并不是其中之一。但是我不明白接口类应该如何实现?

对,你不能做
RationalBase*ptr=newrational(上,下)Rational
之前的code>。(它还不知道要分配多少空间,或者调用什么构造函数)。就我个人而言,我不会使用工厂方法

我会让用户写:

RationalBase* ptr = new Rational(top, bottom);
这使事情变得相当明显

如果你想使用智能指针,那么他们当然也可以编写

std::shared_ptr<RationalBase> ptr(new Rational(top, bottom));
std::unique_ptr<RationalBase> ptr(new Rational(top, bottom)); // ensure only one pointer to this object

我假设您知道可以提供函数体,而不需要声明它们。这样做可以解决这些类型的“定义顺序”问题。

@miguel.martin,当然,如果用户知道他们只需要一个指向它的指针。
shared\u ptr
unique\u ptr
在这里都不合适,@miguel.martin。这里为什么使用指针?这毫无意义
Rational
显然是一个值。@Evan Teran:谢谢。所有这些都是很好的方法。我还是一名初级程序员,所以当我按照书中所说的方式做的时候,我不明白为什么它不起作用,我只是想知道是否有一些标准的方法可以实现它。@KonradRudolph:你可能认为这是一种价值观。然而,我没有对在这里使用纯虚拟基类和指针的适当性做出判断。我认为这是一个留给开发者自己的练习。现在,我只是解释如何实现模式本身。
std::shared_ptr<RationalBase> ptr(new Rational(top, bottom));
std::unique_ptr<RationalBase> ptr(new Rational(top, bottom)); // ensure only one pointer to this object
auto ptr = std::make_shared<Rational>(top, bottom); // C++11
auto ptr = std::make_unique<Rational>(top, bottom); // C++14 only
class Rational;

class RationalBase {
public:
    virtual ~RationalBase () {} // you needed to provide a body to this function

    static RationalBase* create(int top, int bottom);

    virtual int getNumerator () const = 0;
    virtual int getDenominator () const = 0;
    virtual void setNumerator (int) = 0;
    virtual void setDenominator (int) = 0;
};

class Rational : public RationalBase {
public:
    Rational (int top, int bottom) : numerator(top), denominator(bottom) {}
    virtual ~Rational () {}

    virtual int getNumerator () const {
        return numerator;
    }

    virtual int getDenominator () const {
        return denominator;
    }

    virtual void setNumerator (int top) {
        numerator = top;
    }

    virtual void setDenominator (int bottom) {
        denominator = bottom;
    }

private:
    int numerator;
    int denominator;
};

// note that this is defined AFTER the Rational class
RationalBase* RationalBase::create(int top, int bottom) {
    RationalBase* ptr = new Rational(top, bottom);
    return ptr;
}