批评这个c ++代码

时间:2010-07-05 10:10:30

标签: c++

类似于下面编写的代码存在于生产中。你们有人可以审查它并告诉我这些代码是否一直运行良好。

class Base
{
    public:
        virtual void process() = 0;
};

class ProductA : public Base
{
    public:
    void process()
    {
        // some implementation.
        doSomething();
    }

    void setSomething(int x)
    {

    }

    virtual void doSomething()
    {
         // doSomething.
    }

};

class ProductANew : public ProductA
{
    public:
        ProductANew() : ProductA() { }
        void doSomething()
        {
           // do Something.
        }
};


int main(int argc, char *argv[])
{
    Base* bp = new ProductANew();
    dynamic_cast<ProductA*>(bp)->setSomething(10);
    bp->process();
}

4 个答案:

答案 0 :(得分:19)

一些问题:

  • 基类必须具有虚拟析构函数
  • 您永远不会删除使用新
  • 分配的对象
  • 你永远不会测试dynamic_cast的结果

答案 1 :(得分:7)

设计良好,您不需要dynamic_cast。如果在未调用process()的情况下无法调用setSomething(),则它们应该已在同一基类中公开。

答案 2 :(得分:3)

有一个实际错误和一堆危险/可疑的做法:


一个错误是您永远不会在delete ed对象上调用new,因此它会泄漏。


可疑行为:

  1. Base没有虚拟析构函数,因此如果您通过调用delete或使用auto_ptr来更正错误,则会调用未定义的行为。
  2. 根本不需要在这里使用动态分配。
  3. 多态基类应该是不可复制的,以防止对象切片。
  4. 您使用的是dynamic_cast,但并未检查结果 - 为什么不将bp声明为ProductANewProductNew的指针?
  5. ProductANew不需要构造函数 - 默认构造函数也可以。
  6. 这些点中的一些可能是您的示例性质的结果 - 即您有充分的理由使用动态分配,但您希望保持您的示例小。

答案 3 :(得分:1)

一般来说,你会发现甚至无法编译的代码设计得很糟糕。

Base* bp = new ProductANew();

此行无效,因为ProductANew不以任何方式,形状或形式从Base继承。

$ gcc junk.cc
junk.cc: In function ‘int main(int, char**)’:
junk.cc:41: error: cannot convert ‘ProductANew*’ to ‘Base*’ in initialization

(只是要明确:junk.cc包含你的代码剪切和粘贴。)


已编辑添加...

迟到者可能希望在投票前查看原始问题的历史。 ;)