C++ 如何安全地检查a类是否已在C++;?
哦,该死的,我太笨了:-(,我可以用一个布尔数组来达到目的 例如,我收到一个指针C++ 如何安全地检查a类是否已在C++;?,c++,oop,C++,Oop,哦,该死的,我太笨了:-(,我可以用一个布尔数组来达到目的 例如,我收到一个指针p_class 那么如何检查p_class是否指向实例化的类呢 我的意思是,即使这个类没有被实例化,这个类的每个函数仍然可以被调用;如果我试图访问这个类中的一个变量,我可能会访问一些非法的地址,程序就会崩溃 嗯,我想写一个网络库。 由于lib必须支持许多协议 the_lib { public: int selectProtocol(prtcl/*an enum*/ p) { switc
p_class
那么如何检查p_class
是否指向实例化的类呢
我的意思是,即使这个类没有被实例化,这个类的每个函数仍然可以被调用;如果我试图访问这个类中的一个变量,我可能会访问一些非法的地址,程序就会崩溃
嗯,我想写一个网络库。
由于lib必须支持许多协议
the_lib
{
public:
int selectProtocol(prtcl/*an enum*/ p)
{
switch(p)
{
case tcp:
t=new tcp;
....
}
}
int setTCP(opt,para)
{
switch(opt)
{
case csum:
t->setcsum(para)
break;
....
}
int setUDP(opt,para);
....
private:
TCP *t=0;
UDP *u=0;
...
}
因此,如果用户首先选择UDP,但调用
setTCP
,我必须确定是否实际调用classTCP
中的函数您可以通过不使用裸指针,而是使用智能指针来解决问题。std::unique_ptr
和std::shared_ptr
都有bool
conversion运算符,允许您测试指针是否有效
class Foo { /* ... */ };
void foo (const std::unique_ptr<Foo> &p) {
if (!p) { /* ... */ }
}
void foo (const std::shared_ptr<Foo> &p) {
if (!p) { /* ... */ }
}
std::unique_ptr<Foo> p(new Foo);
std::shared_ptr<Foo> q = std::make_shared<Foo>();
最好的做法是不要使用指针。
但是如果您需要引用某个对象,那么就使用引用!在一段格式良好的代码中,引用保证指向某个对象,因此您希望调用的任何方法都保证可以安全地被调用
但在那些确实需要使用指针的情况下,那么:
1.不要使用原始指针。使用智能指针。
std::unique_ptr
几乎总是大多数情况下最好的智能指针。如果需要共享语义,请使用std::shared_ptr
。但请记住:始终首选std::unique_ptr
大多数智能指针的好处是,它们在构造时已经为您进行了一些默认初始化,而没有进行初始化。大多数情况下,它们将内部指针表示形式设置为nullptr
2.不需要对象的所有权?只想保留一个引用,但想能够设置nullptr
?
Useboost::optional
boost::optional
专门用于接口与指针非常相似的引用,但更安全,因为它与智能指针的初始化技术相同
3.真的需要使用原始指针吗?如果它不指向某个对象,请始终将其设置为nullptr
。
上述三种技术的要点是:由于值为
nullptr
的指针不指向某个有效对象,因此可以使用它检查指针是否指向有效对象
通过这种方式,您的代码可以检查它是否未初始化(p_实例==nullptr
)或未初始化(p_实例!=nullptr
)。此外,使用nullptr
会增加在无效对象上执行操作时发生运行时错误的机会,尽管该行为在很大程度上依赖于实现
检查和使用指针的一般模式为:
if(ptr) {
ptr->do_something();
}
但是如果你真的,真的需要调用
do_something()
。如果你提供更多的细节,有人可能会想出一个更有用的答案。闻起来像是糟糕的OO设计和由此产生的空洞点魔法。我们需要示例代码向您展示如何处理您当前面临的问题。
MyClass instance;
instance.do_something(); // guaranteed to be safe to call
MyClass* p_instance = nullptr;
// Use p_instance, perhaps assign to it
p_instance = nullptr; // You don't need to use the pointed-to object
if(ptr) {
ptr->do_something();
}