如何安全地检查一个类是否已在C ++中实例化?

时间:2014-03-01 04:37:24

标签: c++ oop

该死的我真是太蠢了:-(我可以用一个bool阵列达到目的

例如,我收到一个指针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,我必须确定是否实际调用类TCP中的函数

2 个答案:

答案 0 :(得分:1)

0。最好的办法是什么? 不要使用指针。

MyClass instance;
instance.do_something();   // guaranteed to be safe to call

但是如果你需要引用到某个对象,那么使用引用!在一个格式良好的代码中,保证引用指向某个对象,因此保证您调用的任何方法都是安全的。

但是在那些你确实需要使用指针的情况下,那么:

1。不要使用原始指针。使用智能指针。

对于大多数情况,

std::unique_ptr几乎总是最好的智能指针。如果您需要共享语义,请使用std::shared_ptr。但请记住:总是更喜欢std::unique_ptr

大多数智能指针的好处在于,它们在未经初始化的情况下构建时已经为您进行了一些默认初始化。大多数情况下,他们将内部指针表示设置为nullptr

2。不需要对象的所有权?只想保留参考但希望能够设置nullptr

使用boost::optional<T&>boost::optional有一个特殊的引用,其接口非常类似于指针,但只是更安全,因为它使用与智能指针相同的初始化技术。

3。真的需要使用原始指针来达到一些难以想象的原因吗?然后,当它不是指向某个对象时,始终将其设置为nullptr

MyClass* p_instance = nullptr;
// Use p_instance, perhaps assign to it
p_instance = nullptr;   // You don't need to use the pointed-to object

以上三种技术的要点是这样的:因为值为nullptr的指针不指向某个有效对象,那么您可以使用它来检查指针是否指向有效对象与否

通过这种方式,您的代码可以检查它是否未初始化(p_instance == nullptr)(p_instance != nullptr)。此外,使用nullptr会增加在对无效对象执行操作时出现运行时错误的几率,尽管该行为与实现有很大关系。

检查和使用指针的一般模式是:

if(ptr) {
   ptr->do_something();
}

但是,如果你真的,真的需要拨打do_something()怎么办?然后我们又回归零。 :)

答案 1 :(得分:0)

您可以通过不使用裸指针和使用智能指针来解决您的问题。 std::unique_ptr<>std::shared_ptr<>都有bool个转换运算符,可以让您测试指针是否有效。

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>();

如果您没有执行动态分配,那么请避免使用指针,并将对象传递给接受引用的函数。

void foo (const Foo &f) {
    //...
}