我正在围绕sqlite3编写一个非常简单的小包装器,并使用sqlite3_get_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;}
};
record
的{{1}}(operator[]
)允许我以这种方式访问基础inline data* operator [](ushort field);
课程:
data
并在Arch Linux下编译:{{1}},编译时没有问题。但是当我运行它时,我得到db::str* mys = dynamic_cast<db::str*>((*record)[3]);
。
评论dynamic_cast行让我感到高兴,但我个人认为我在某种程度上做错误,而不是认为定义或使用g++ -o main -lsqlite3 main.cpp
类时存在问题。
我也很欣赏我的代码中的任何激进攻击,因为我知道我是新手。非常感谢。
答案 0 :(得分:1)
当您使用dynamic_cast
时,您需要检查结果以查看它是否为NULL
。当对象实际上不是您尝试转换为的类型的实例时,会发生这种情况。
答案 1 :(得分:1)
你没有downcast
,你正在做upcast
。 data
类是operator[]
返回的基础,您将其投射到db::str*
,这是一个孩子。并非每个data
都是str
,因此对于初学者来说,您应该检查您尝试投射的是str
以及投射是否不返回0。
此外,您应该习惯使用Valgrind,尤其是memcheck工具。您可以在几秒钟内确定地点和原因,并且作为Arch用户自己,我保证它在回购中。您使用valgrind --tool=memcheck ./myprogram
运行程序。
答案 2 :(得分:1)
感谢TC1和Mark Ransom。我试着解决我的问题,我终于意识到这是最好的解决方案,比较它的优点与它的权衡,对于一个简单的包装,就像我正在编写的那样(sqlite3的sqlite3_get_table()
):
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.
};
这样我就使数据*成为一个非常合适的指针类型,用于制作异构容器(很抱歉,当我提出问题时,我不知道这个词;-))在这种情况下,数据类型有限,在这种情况下为5,因为它的工作水平较低。
我刚刚在我的测试main
中使用过它:
data* array[3];
array[0] = new data(3);
cout << *(array[0]);
它确实给了我3
,当然它也可以将它应用到任何其他类型,特别是在低级别,在这种情况下类型通常是基本的而不是复杂的继承类型。
我开始相信在这种情况下static_cast
可以被容忍,如果我错了,请纠正我。此外,我非常愿意了解您对此解决方案的批评和赞赏,因为它有助于我作为初学者学习更多内容。
谢谢。