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

发布于 2024-09-30 09:34:30 字数 1942 浏览 2 评论 0原文

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

相关代码

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

以下是查找表:

#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

How do I verify that an object being pointed by a pointer is valid

relevant code

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

Here is what Lookup table is:

#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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

烧了回忆取暖 2024-10-07 09:34:30

table 是一个LookupTable。为什么它会包含一个不是 Product* 的指针?这没有任何意义。

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

  • 通过一些复杂的转换,您将一个指向非 Product 的指针插入到 table 中。唯一的解决方案是“不要这样做。”

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

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

table is a LookupTable<Product*>. Why would it contain a pointer that isn't a Product*? That doesn't make any sense.

You shouldn't ever need to do this. The only reasons you would need to do this are if:

  • Through some convoluted cast you inserted a pointer to something that isn't a Product into table. The only solution to this is "don't do that."

  • You have a pointer to what was a Product object, but you've screwed up your object lifetime management and you destroyed the object before you were done with it. The solution to this is to use scope-bound resource management (SBRM, also called Resource Acquisition is Initialization, or RAII), which allows lifetimes to be automatically managed. Use a smart pointer container like shared_ptr/weak_ptr to facilitate this.

  • You put a null pointer into the table. In this case, you can either just not put null pointers into the lookup table, or check whether a pointer is null after you obtain it from the table.

虫児飞 2024-10-07 09:34:30

基于您在后续问题中发布的LookupTable代码,这个问题终于可以回答了。 (真的,我认为您应该将该代码放在这里并删除其他问题。)

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

因此,对于代码中的 LookupTable,表达式 table[selection] 要么将结果放入指向 Product 的指针中code> 在表中找到,或者是 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;
}

Based on the code of LookupTable that you posted in a subsequent question, this question can finally be answered. (Really, I think you ought to just put that code here and remove the other question.)

table[selection] either returns a reference to an entry in the table (if the selection is found) or otherwise a reference to a default-initialized object. When LookupTable is specialized for a pointer type (such as the Product* in your code) then the default-initialized object will be a NULL pointer.

So, for the LookupTable<Product*> in your code, the expression table[selection] is either going the result in a pointer to a Product found within the table or else a NULL Product pointer.

Consequently, instead of immediately dereferencing the result of table[selection] and trying to assign it to a Product object, you should actually take the pointer value and examine it.

This would be accomplished with code similar to:

Product* result = table[selection];
if(result != NULL)
{
    Product temp = *result;
    // do something with temp, etc, etc
}
else
{
    cout << "invalid product code" << endl;
}
北城半夏 2024-10-07 09:34:30

您可以使用dynamic_cast

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

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

You can use dynamic_cast:

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

But DON'T DO THIS. If you find yourself needing to take specific action based on the runtime type of an object, you're almost certainly doing something wrong. This is what virtual functions are for.

吃颗糖壮壮胆 2024-10-07 09:34:30

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

It sounds like you need dynamic_cast. But your design also sounds suspect. Why would your collection not contain the right types ? Or, if you need to make decisions based upon the type of your object, then some form of polymorphism is what you'd most likely require.

枕花眠 2024-10-07 09:34:30

您可以使用 RTTI。包含 标头,并说:

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

但是这里有些东西确实可疑...上面的语句基本上是同义反复,您不需要这样做根本不。 C++ 是一种强类型语言,因此根据定义,包含在 Product 对象容器中的任何对象都是 Product 的实例 - 除非您做了一些荒谬的事情,例如插入使用reinterpret_cast将无效对象放入容器中。

You can use RTTI. Include the <typeinfo> header, and say:

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

But something is really fishy here... the above statement is basically tautological, and you shouldn't need to do this at all. C++ is a strongly typed language, and so any object contained in a container of Product objects is, by definition, an instance of Product - unless you did something ridiculous, like inserting an invalid object into the container using a reinterpret_cast.

时光是把杀猪刀 2024-10-07 09:34:30
Product * temp = dynamic_cast<Product*>(table[selection]);
if (temp) {
   do something
}

并继续执行此操作。人们会告诉你不要这样做,但不要听他们的。

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

and GO AHEAD AND DO THIS. People will tell you not to, but don't listen to them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文