C++ C++;通过多态性和指针定制异构容器
我正在围绕sqlite3编写一个非常简单的小包装,并使用sqlite3\u get\u table()以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);
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]);