C ++指向指针的指针(x **) - > (Y **)

时间:2014-12-04 22:09:35

标签: c++ pointers casting

我是C ++的新手,我决定尝试使用指针指针。我正在尝试创建一个系统,我可以使用它和抽象类来定义许多不相关的类可以继承的接口(通常通过多重继承),这样我就可以将它们推送到一些常见的辅助函数。

我尽可能地将代码煮熟,所以如果列表有点长,我会道歉......

//------------ HEADER

struct IClassData
{
    virtual int Width() = 0;
    virtual int Height() = 0;
};

class ClassA
{
    public:
        ClassA(int w, int h);

        protected:
            int _Width;
            int _Height;
};


class Derived : public ClassA, public IClassData
{
    public:
        Derived();
        Derived(int w, int h);

    virtual int Width() override;
    virtual int Height() override;
};

class Computron
{
public:
    static int TotalWidth(IClassData** data, int size)
    {
        int curSum = 0;
        for (int i = 0; i < size; i++)
        {
            curSum += data[i]->Width();
        }

        return curSum;
    }
};

// -------------- CPP
ClassA::ClassA(int w, int h)
{
    _Width= w;
    _Height = h;
}

Derived::Derived() : ClassA(0,0) { /* NONE */ } 
Derived::Derived(int w, int h) : ClassA(w,h) { /* NONE */ } 

int Derived::Width() { return _Width; }
int Derived::Height() { return _Height; }

所以在我的主程序中,我创建了一些派生类的实例,我想做一些转换,以便它可以像这样对计算机函数起作用:

// --------------- MAIN

...
const int MAX = 5;
    Derived** data = new Derived*[MAX];

    for (int i = 0; i < MAX; i++)
    {
        data[i] = new Derived(i, i*2);
    }

    // Cast an compute
    int size = Computron::TotalWidth((IClassData**)data, MAX);
...

所以我的重要问题是:
  1.这是一件好事吗,还是我以后会自己开枪?我意识到我的课程在这里非常简单,但如果它们变得非常复杂会导致一些问题吗?   2.此外,由于某种原因,这样的演员是否有可能在运行时无效?   我最好只为这些类型的场景使用模板吗?

1 个答案:

答案 0 :(得分:0)

  

这是一件好事,还是我以后会自己开枪?我意识到我的课程在这里非常简单,但是如果它们变得非常复杂会引起一些问题吗?

我在这里看不到任何通常引起麻烦的事情,但我强烈建议使用标准库以避免以后出现内存管理问题。例如,我将使用:

代替您的数组
std::vector<std::unique_ptr<Derived>> data;

data超出范围时,矢量将被销毁。这反过来会导致unique_ptr被销毁,并且它们会自动删除Derived个对象。

但是,您只需要指针需要多态并在同一个数组中存储不同类型的对象;也就是说,如果要存储指向IClassData对象的指针,那么在运行时不确切知道数组中将出现什么派生类型的情况下,您更有可能需要这样做。如上所述,您可以简单地使用std::vector<Derived>,因为您知道所有对象都是Derived个实例。

  

此外,由于某些原因,这样的演员是否有可能在运行时无效?

不要在C ++中使用C风格的强制转换。您应该在此处使用static_cast,并使用 it doesn't even work at compile time ,因为它违反了类型系统。

Derived ** a = new Derived*[MAX];
Base ** b = static_cast<Base **>(a); // This line will not compile, because...

b[0] = new Base();           // Now a[0] is a Base rather than a Derived??
a[0]->some_derived_method(); // What should happen!?!?
  

我最好只为这些类型的场景使用模板吗?

每种情况都不同,所以答案是肯定的“也许”。