繁体   English   中英

如何使用结构作为接口从函数返回指向数组的指针

[英]how do I return a pointer to an array from a function using a struct as the interface

我试图在C ++中创建数组的接口。


在下面的代码中
tmpClass[1].GetA()返回'w'
tmpInterface[1]导致错误。

有没有什么方法可以定义接口,以便它可以访问数组的元素?
如何使tmpInterface表现得像tmpClass

struct IA
{
    virtual char GetA() = 0;
    virtual void SetA(char pA) = 0;
};

class A:public IA
{
    public:
        A(){ var = 0; }
        A(char pVar){ var = pVar; }
        char GetA(){ return var; }
        void SetA(char pA){ var = pA; }
    private:
    int var;
};

class B
{
    public:
        B(){ 
            mA[0].SetA('c');
            mA[1].SetA('w');
            mA[2].SetA('6');
            mA[3].SetA('$');
        }

        int GetCount(){}
        IA* Get1(){ return mA; }
        A* Get2(){ return mA; }
    protected:
        A mA[4];
};


int main()
{
    B mainClass;
    IA *tmpInterface = mainClass.Get1();
    A *tmpClass = mainClass.Get2();

    for (int i = 0; i < 4; i++)
    {
        //once i>0 then tmpInterface no longer points to a valid character
        //and program crashes
        System::Console::Write(
            "A = "+tmpClass[i].GetA()+
            " IA = "+tmpInterface[i].GetA()); 
    }
    return 0;
}

下标运算符使用指针算术,并且对类型与其所指向对象的实际类型不同的指针执行指针算术,这是未定义的行为。 §5.7[expr.add] / p7:

对于加法或减法,如果表达式PQ类型为“ cv T指针”,其中T与cv不合格数组元素类型不同,则该行为是不确定的。 [ 注意 :特别地,当数组包含派生类类型的对象时,不能将指向基类的指针用于指针算术。 尾注 ]

因此,要索引到A的数组中,您需要A* 如果您只想使用IA ,则需要应用一些程序员的灵丹妙药-间接。 返回指向IA *数组的第一个元素的IA ** ,该数组的成员每个都指向A

请注意,多态仅适用于指向类实例的指针或引用,不适用于直接与实例联系的实例。 这是问题的根源。

您可能会考虑使用std::vector<A*>而不是数组。

在有效的C ++中,它说不要在数组上使用多态性。 您可以添加一个虚拟函数,其行为类似于运算符[],例如:

struct IA
{
    //...
    virtual IA* Offset(int index)
    {
        return this + index;
    }
};

class A:public IA
{
public:
    //...
    virtual A* Offset(int index)
    {
        return this + index;
    }
};

然后就可以了

cout << "A = " << tmpClass->Offset(i)->GetA();
cout << " IA = " << tmpInterface->Offset(i)->GetA() << endl;

此外,C ++中的System :: Console :: Write是什么?

在类型B的对象中,您具有A对象的数组。 您在两个成员函数B::Get1()B::Get2()中都返回一个指向数组第一个元素的指针。

假设布局数组为:

+--------------+--------------+--------------+--------------+
|    mA[0]     |    mA[1]     |    mA[2]     |    mA[3]     |         
+--------------+--------------+--------------+--------------+

执行时

IA *tmpInterface = mainClass.Get1();
A *tmpClass = mainClass.Get2();

您有tempInterfacetmpClass指向mA的第一个元素。

+--------------+--------------+--------------+--------------+
|    mA[0]     |    mA[1]     |    mA[2]     |    mA[3]     |         
+--------------+--------------+--------------+--------------+
^
| 
tmpInterface as well as tmpClass

tmpInterfacetmpClass上进行算术运算时,您会看到非常不同的结果。

tmpInterface+1tmpClass+1指向哪里?

+--------------+--------------+--------------+--------------+
|    mA[0]     |    mA[1]     |    mA[2]     |    mA[3]     |         
+--------------+--------------+--------------+--------------+
      ^        ^
      |        | 
      |        tmpClass+1
      tmpInterface+1

由于tmpClass的类型为A* ,因此tmpClass+1指向数组中的下一个对象。 但是,由于tmpInterface的类型为IA* ,并且sizeof(IA)sizeof(A) ,因此tmpInterface+1指向中间的某个内容。 它没有指向IA类型的对象。 如果您尝试以IA*访问tmpInterface+1 ,那么您将获得未定义的行为。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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