1

我的问题如下:

int main()
{
    Base* derivedobject = new Derived1();
    derivedobject->GetProperties()-> ???

return 0;
}

//********************
// BaseClass.h
//********************
struct PropertyStruct
{
    int x;
};

class Base
{
public:
    Base();
    ~Base();

    virtual PropertyStruct GetProperties() = 0;

private:
};

//********************
// DerivedClass1.h
//********************
struct PropertyStruct
{
    int y;
};

class Derived1 : public Base
{
public:
    Derived1();
    ~Derived1();

    PropertyStruct GetProperties() { return myOwnDifferentProperties; };

private:

};

//********************
// DerivedClass2.h
//********************
struct PropertyStruct
{
    float z;
};

class Derived2 : public Base
{
public:
    Derived2();
    ~Derived2();

    PropertyStruct GetProperties() { return myOwnDifferentProperties };

private:

};

如果我这样做,我会得到一个错误,说 PropertyStruct 是一个重新定义。如果我在派生类中使用命名空间或重命名结构,则会收到一个错误,告诉我返回类型与 Base 定义的不同。如果我将虚函数返回类型定义为它编译的指针,尽管从主方法(在本例中)访问函数“GetProperties”时的下一个问题是基对象不知道派生类的结构内有哪些变量.

有什么办法可以让我意识到这一点?我可以获得每个派生对象的不同属性但使用基类对象吗?

4

3 回答 3

2

正如其他人所提到的,有一些方法可以在这里实现您的目标,但最终您会发现自己编写如下代码:

    Base * object = ...;

    if object is Derived1 then
      get Property1 and do something with it
    else if object is Derived2 then
      get Property2 and do something with it

这是面向对象编程中的反模式。您已经有一个类层次结构来表示各种派生类型之间的差异。与其从对象中提取数据并在外部进行处理,不如考虑向基类添加一个虚函数并让派生类进行处理。

class Base
{
public:

    virtual void DoSomething() = 0;
};

class Derived1 : Base
{
public:

    void DoSomething()
    {
        // use myOwnDifferentProperties as necessary
    }

private:

    PropertyStruct myOwnDifferentProperties;
};

如果将所需的处理放在派生类中是不合适的(即,如果它会引入不需要的责任),那么您可能需要考虑将访问者模式作为扩展层次结构功能的一种方式。

于 2012-07-26T16:14:30.660 回答
0

由于模板函数不能是虚拟的,因此您可以使用属性的层次结构。这只是一种方式,没有其他方式。对于派生属性的获取元素,您应该使用虚拟 getter 函数。

struct BaseProp
{
    virtual ~BaseProp() { }
    virtual boost::any getProperty() const = 0;
};

struct PropertyStruct : BaseProp
{
    boost::any getProperty() const { return x; }
private:
    int x;
};

struct PropertyStruct2 : BaseProp
{
    boost::any getProperty() const { return y; }
private:
    float y;
};

class Base
{
public:
    virtual std::shared_ptr<BaseProp> GetProperties() const = 0;
    virtual ~Base() { }
}

class Derived
{
public:
    std::shared_ptr<BaseProp> GetProperties() const { return new PropertyStruct(); }
};

class Derived2
{
public:
    std::shared_ptr<BaseProp> GetProperties() const { return new PropertyStruct2(); }
};
于 2012-07-26T15:41:07.410 回答
0

您可以使用模板类来做到这一点:

struct PropertyStruct1 {
    float f;
};

struct PropertyStruct2 {
    int i;
};

template<class T>
class A{
public:
    T GetProperties() {return mProps;}

private:
    T mProps;   
};

int main (int argc, const char * argv[]) {

    A<PropertyStruct1> a1;
    int f = a1.GetProperties().f;
    A<PropertyStruct2> a2;
    int i = a2.GetProperties().i;
    return 0;
}
于 2012-07-26T15:55:52.013 回答