Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/magento/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 批评这个c++;代码_C++ - Fatal编程技术网

C++ 批评这个c++;代码

C++ 批评这个c++;代码,c++,C++,与下面编写的代码类似的代码也存在于生产环境中。你们能不能检查一下,告诉我这样的代码是否一直运行良好 class Base { public: virtual void process() = 0; }; class ProductA : public Base { public: void process() { // some implementation. doSomething(); } v

与下面编写的代码类似的代码也存在于生产环境中。你们能不能检查一下,告诉我这样的代码是否一直运行良好

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();
}
类基
{
公众:
虚空进程()=0;
};
类别A:公共基础
{
公众:
无效过程()
{
//一些实施。
doSomething();
}
无效设置值(整数x)
{
}
虚空剂量测定法()
{
//做某事。
}
};
类别ProductANew:公共产品A
{
公众:
ProductANew():ProductA(){}
无效剂量测定法()
{
//做点什么。
}
};
int main(int argc,char*argv[])
{
Base*bp=newproductanew();
动态铸造(bp)->设定值(10);
bp->process();
}

良好的设计不需要
动态演员
。如果不先调用
setSomething()
就不能调用
process()
,那么它们应该在同一个基类中公开。

如果设计好,就不需要
动态转换。如果不先调用
setSomething()
就不能调用
process()
,那么它们应该在同一基类中公开。

一些问题:

  • 基类必须具有虚拟析构函数
  • 您永远不会删除分配给新用户的对象
  • 您从不测试动态_cast的结果
一些问题:

  • 基类必须具有虚拟析构函数
  • 您永远不会删除分配给新用户的对象
  • 您从不测试动态_cast的结果

通常,您会发现甚至无法编译的代码设计得很糟糕

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包含剪切和粘贴的代码。)


编辑以添加


迟到的人可能想在否决投票前查看原始问题的历史记录

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

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包含剪切和粘贴的代码。)


编辑以添加


迟到的人可能想在否决投票前查看原始问题的历史记录

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


一个错误是,您从未对
新对象调用
delete
,因此它会泄漏


可疑做法:

  • Base
    没有虚拟析构函数,因此如果通过调用
    delete
    或使用
    auto_ptr
    来更正错误,则将调用未定义的行为
  • 这里根本不需要使用动态分配
  • 多态基类应该是不可压缩的,以防止对象切片
  • 您正在使用一个
    动态\u cast
    ,它不是必需的,并且没有检查结果-为什么不直接声明
    bp
    作为
    ProductANew
    ProductNew
    的指针
  • ProductANew
    不需要构造函数-默认构造函数就可以了

  • 其中有几点可能是示例性质的结果,即您有充分的理由使用动态分配,但您希望示例保持较小。

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


    一个错误是,您从未对
    新对象调用
    delete
    ,因此它会泄漏


    可疑做法:

  • Base
    没有虚拟析构函数,因此如果通过调用
    delete
    或使用
    auto_ptr
    来更正错误,则将调用未定义的行为
  • 这里根本不需要使用动态分配
  • 多态基类应该是不可压缩的,以防止对象切片
  • 您正在使用一个
    动态\u cast
    ,它不是必需的,并且没有检查结果-为什么不直接声明
    bp
    作为
    ProductANew
    ProductNew
    的指针
  • ProductANew
    不需要构造函数-默认构造函数就可以了

  • 其中有几点可能是示例性质的结果,即您有充分的理由使用动态分配,但您希望示例保持较小。

    我猜
    类产品A
    的定义实际上应该从
    类产品A:public Base
    开始,您关心的是什么-动态转换?这是从哪里来的/为什么你不能使用ProductA*而不是Base*-你是否将你的ProductA存储在一个公共数组或类似的数组中?其中是否有一个特定的问题,比如这种使用dynamic_cast的方式是否总是有效等?对于记录,如果RTTI不适合,dynamic_cast可能会给您一个空指针,您可以直接取消引用,而无需检查。但是otoh,如果这真的是您的生产代码,并且像这样实例化之后立即进行转换,那么您就不用担心了。哦,你的产品A不是从基地继承的…产品A是从基地继承的吗?是的。。我刚刚更新了代码。我猜
    class ProductA
    的定义应该从
    class ProductA:public Base
    开始,你关心的是什么-动态演员阵容?这是从哪里来的/为什么你不能使用ProductA*而不是Base*-你是否将你的ProductA存储在一个公共数组或类似的数组中?其中是否有一个特定的问题,比如这种使用dynamic_cast的方式是否总是有效等?对于记录,如果RTTI不适合,dynamic_cast可能会给您一个空指针,您可以直接取消引用,而无需检查。但是otoh,如果这真的是您的生产代码,并且像这样实例化之后立即进行转换,那么您就不用担心了。哦,你的产品也不好