C++ C++;通过多态性和指针定制异构容器

C++ C++;通过多态性和指针定制异构容器,c++,inheritance,casting,C++,Inheritance,Casting,我正在围绕sqlite3编写一个非常简单的小包装,并使用sqlite3\u get\u table()以char**的形式获取结果。我使用一个基本数据类来将字段存储在一个统一的容器中,即记录在这里,然后专门使用派生类型获取每个数据类型 这是我的基类: class data { private: uint sz; virtual void abstract() = 0; public: inline data(char* pd);

我正在围绕sqlite3编写一个非常简单的小包装,并使用sqlite3\u get\u table()以
char**
的形式获取结果。我使用一个基本数据类来将字段存储在一个统一的容器中,即记录在这里,然后专门使用派生类型获取每个数据类型

这是我的基类:

class data
{
    private:
        uint sz;
        virtual void abstract() = 0;

    public:
        inline data(char* pd);
        inline data();
        uint size() {return sz;}
};
下面是示例派生类:

class str : public data
{
    private:
        string* pdata;
        virtual void abstract() {}

    public:
        inline str(char* pd);
        inline operator string();
        inline operator const char*();
};
记录类:

class record
{
    private:
        ushort cols;
        data** entries;
    public:
        record(char** ppdata, uint col_count);
        inline data* operator [](ushort field);
        inline uint num_fields() {return cols;}
};
记录
运算符[]
内联数据*运算符[](ushort字段);
)允许我通过以下方式访问基本
数据
类:

db::str*mys=dynamic_cast((*record)[3])

在Arch Linux下编译:
g++-o main-lsqlite3 main.cpp
,编译没有问题。但是当我运行它时,我得到了
分段错误

注释掉dynamic_cast行让我很高兴,但我个人认为我在某种程度上犯了向下投射的错误,而不是认为
数据
类的定义或使用有问题


我也很欣赏对我的代码的任何激进的冒犯,因为我知道我是一个新手。非常感谢。

当您使用
dynamic\u cast
时,您需要检查结果是否为
NULL
。当对象实际上不是您试图转换到的类型的实例时,就会发生这种情况。

当您使用
动态\u cast
时,需要检查结果是否为
NULL
。当对象实际上不是您试图强制转换到的类型的实例时,就会发生这种情况。

您不是在执行
向下强制转换
,而是在执行
向上强制转换
data
类是由
操作符[]
返回的基,您将其强制转换为
db::str*
,它是一个子类。并不是每个
数据都是
str
,因此,对于初学者,您应该检查您尝试强制转换的内容是否是
str
,以及强制转换是否不返回0


另外,你应该习惯于使用,尤其是它的工具。你可能会在几秒钟内找到原因,作为一名主要用户,我向你保证,它在回购协议中。您使用
valgrind--tool=memcheck./myprogram
运行程序,您不是在执行
向下播放
,而是在执行
向上播放
data
类是由
操作符[]
返回的基,您将其强制转换为
db::str*
,它是一个子类。并不是每个
数据都是
str
,因此,对于初学者,您应该检查您尝试强制转换的内容是否是
str
,以及强制转换是否不返回0


另外,你应该习惯于使用,尤其是它的工具。你可能会在几秒钟内找到原因,作为一名主要用户,我向你保证,它在回购协议中。您可以使用
valgrind--tool=memcheck./myprogram
运行您的程序,谢谢您TC1和Mark Ransom。我试着处理我的问题,最后我意识到这是最好的解决方案,比较它的优点和利弊,对于我正在编写的简单包装(sqlite3的
sqlite3\u get\u table()
):

它确实给了我
3
,当然它也有可能应用于任何其他类型,特别是在低级别,在这种情况下,类型通常是基本的,而不是复杂的继承类型

我开始相信,在这种情况下,
static\u cast
是可以容忍的,如果我错了,请纠正我。我也非常愿意知道你们对这个解决方案的批评和赞赏,因为它帮助我作为一个初学者学到了更多


谢谢。

谢谢你们TC1和马克·兰森。我试着处理我的问题,最后我意识到这是最好的解决方案,比较它的优点和利弊,对于我正在编写的简单包装(sqlite3的
sqlite3\u get\u table()
):

它确实给了我
3
,当然它也有可能应用于任何其他类型,特别是在低级别,在这种情况下,类型通常是基本的,而不是复杂的继承类型

我开始相信,在这种情况下,
static\u cast
是可以容忍的,如果我错了,请纠正我。我也非常愿意知道你们对这个解决方案的批评和赞赏,因为它帮助我作为一个初学者学到了更多


谢谢。

这张
唱片在哪里?添加多态行为应该可以避免这种负面影响。我刚刚添加了record类。它除了包含指向
数据
s的指针外,没有其他功能。@sje397是的,我的目标是添加多态行为,但我应该走错方向。我需要你的帮助!;-)这个
记录在哪里
类?添加多态行为应该可以避免这种负面影响。我刚刚添加了record类。它除了包含指向
数据
s的指针外,没有其他功能。@sje397是的,我的目标是添加多态行为,但我应该走错方向。我需要你的帮助!;-)我只是将动态_cast行替换为
db::data*pd=(*r)[3]并且我没有得到分段错误
cout@ai64,您在问题中没有包含足够的信息,无法了解
dynamic\u cast
不起作用的原因。不过,该指针值看起来可疑。我想看看你在填充
r
。我从来没有使用过G++,但是你需要以某种方式启用RTTI吗?(找出Microsoft VS user.:-)我的目标是:将不同类型的数据(字符串、int、float、blob和none)存储在一个统一的数组中,称为record。你有什么建议?我确信这是CS中非常常见的问题,必须有科学正确的C++解决方案,我不知道。我在这里寻找
enum types {INT, FLOAT, STRING, BLOB, NUL};

class bad_type {};

class data
{
    private:
        void* pdata;
        types type;

    public:
        data(int dt)
        {
            int* tmp = new int(dt);
            pdata = static_cast<void*>(tmp);
            type = INT;
        }
        // constructors for other types to be added in a similar fashion.

        operator int()
        {
            if (type == INT)
                return *(static_cast<int*>(pdata));
            throw bad_type();
        }
        // operators for other types to be added in a similar fashion.
};
data* array[3];
array[0] = new data(3);

cout << *(array[0]);