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,如果这真的是您的生产代码,并且像这样实例化之后立即进行转换,那么您就不用担心了。哦,你的产品也不好