c ++指向对象类型检查的指针

时间:2010-11-03 23:56:55

标签: c++ class pointers types object

如何验证指针指向的对象是否有效

相关代码

LookupTable<Product *> table;
Product temp = *table[selection];
// if *table[selection] is not a product, program crashes...

以下是Lookup表:

#ifndef LOOKUPTABLE_H
#define LOOKUPTABLE_H

#include <iostream>
#include <string>

using namespace std;

#define MAXRANGE 10

template <class T>
class LookupTable
{
private:
    T *aptr[MAXRANGE];
    int rangeStart[MAXRANGE];
    int rangeEnd[MAXRANGE];
    int numRanges;

public:
    T defaultValue;
    bool failedRangeCheck;
    std::string failReason;


    // Constructor
    LookupTable() 
    {   
        numRanges = 0; 
        defaultValue = T();
    }      

    void addRange(int start, int end)
    {
        std::cout << "Created a new range...  Start: " << start << " / End: " << end << endl;
        failedRangeCheck = false;

        //lines omitted because not working anyway

        if ( !failedRangeCheck )
        {
            //set ranges
            rangeStart[numRanges] = start;
            rangeEnd[numRanges] = end;

            //build new generic array with end-start+1 positions
            //set pointer to point to it
            aptr[numRanges] = new T[ end - start + 1 ];
            numRanges++;
        }
        else
        {
            std::cout << "Range overlapped another range." << endl;
            std::cout << failReason << endl;
        }
    }

    T &operator[](int value)     // Overloaded [] operator
    {
        for ( int i = 0; i < numRanges; i++ )
        {
            if ( (value >= rangeStart[i]) && (value <= rangeEnd[i]) )
            {
                return aptr[i][value - rangeStart[i]];
            }
        }

        return defaultValue;
    }

    ~LookupTable()
    {
         delete[] aptr;
         numRanges = 0;     
    }

};
#endif

6 个答案:

答案 0 :(得分:3)

tableLookupTable<Product*>。为什么它包含不是Product* 的指针?这没有任何意义。

你不应该这样做。您需要执行此操作的唯一原因是:

  • 通过一些错综复杂的演员,你在Product中插入一个非table的指针。对此的唯一解决方案是“不要那样做。”

  • 你有一个指向Product对象的指针,但你已经搞砸了你的对象生命周期管理,并在你完成之前销毁了对象。解决方案是使用范围限制资源管理(SBRM,也称为资源获取是初始化,或RAII),它允许自动管理生命周期。使用像shared_ptr / weak_ptr这样的智能指针容器来实现此目的。

  • 您将空指针放入table。在这种情况下,您可以不将空指针放入查找表中,或者在从表中获取指针后检查指针是否为空。

答案 1 :(得分:1)

根据您在subsequent question中发布的LookupTable代码,最终可以回答此问题。 (真的,我认为你应该把这些代码放在这里并删除另一个问题。)

table[selection]要么返回对表中条目的引用(如果找到了选择),要么返回对默认初始化对象的引用。当LookupTable专门用于指针类型(例如代码中的Product*)时,默认初始化对象将是NULL指针。

因此,对于代码中的LookupTable<Product*>,表达式table[selection]要么将结果指向表中找到的Product,要么返回NULL Product }指针。

因此,您应该实际获取指针值并检查它,而不是立即取消引用table[selection]的结果并尝试将其分配给Product对象。

这可以使用类似于:

的代码来完成
Product* result = table[selection];
if(result != NULL)
{
    Product temp = *result;
    // do something with temp, etc, etc
}
else
{
    cout << "invalid product code" << endl;
}

答案 2 :(得分:0)

您可以使用dynamic_cast

if (dynamic_cast<Product *>(table[selection])) != NULL)
{
    ...
}

不要这样做。如果您发现自己需要根据对象的运行时类型采取特定操作,那么您几乎肯定会做错事。这就是虚函数的用途。

答案 3 :(得分:0)

听起来你需要dynamic_cast。但你的设计听起来也很可疑。为什么您的收藏品不包含正确的类型?或者,如果您需要根据对象的类型做出决策,那么某种形式的多态性就是您最需要的。

答案 4 :(得分:0)

您可以使用RTTI。添加<typeinfo>标题,然后说:

if (typeid(*table[selection]) == typeid(Product)) { ... }

但是这里的某些东西真的很可疑......上面的陈述基本上是同义反复的,你根本不应该这样做。 C ++是一种强类型语言,因此根据定义,Product对象容器中包含的任何对象都是Product的实例 - 除非你做了一些荒谬的事情,比如在容器中插入一个无效的对象使用reinterpret_cast

答案 5 :(得分:-2)

Product * temp = dynamic_cast<Product*>(table[selection]);
if (temp) {
   do something
}

并且前进并做到这一点。人们会告诉你不要,但不要听他们。