C++:在 C 语言中传递指向模板类的指针
C++: Passing pointer to template class around in C
我正在为我的库编写一个C包装器API。
我通常将我的C++对象作为 C 中的void*
传递。每个对象的公共函数自然都有访问包装器函数。C 代码不访问本机C++类成员。
昨天,有人在 IRC 上提到,我不应该将指向C++模板类的指针传递为 C 语言中的void*
,因为这很危险。这是真的吗?指向普通C++类的指针与指向模板类的指针有何不同?
谢谢!
假的。模板没有普通类所没有的特殊属性重新转换。确保你总是使用适当的石膏,你会没事的。
这与模板与普通类无关,但是如果您的类具有多重继承,则应始终从相同的类型开始,然后再转换为void*
,并且在转换回时也是如此。指针的地址将根据指针类型的父类而更改。
class ParentA
{
// ...
int datumA;
};
class ParentB
{
// ...
int datumB;
};
class Derived : public ParentA, public ParentB
{
// ...
};
int main()
{
Derived d;
ParentA * ptrA = &d;
ParentB * ptrB = &d;
assert((void*)ptrA == (void*)ptrB); // asserts!
}
将一些指针Foo*
投射到void*
上,然后在相同类型的Foo*
上恢复始终是安全的。但是,在使用继承时,应特别注意。不应通过void*
指针进行向上转换/向下转换。请考虑以下代码:
#include <cassert>
class Parent
{
int bar;
};
class Derived : public Parent
{
virtual void foo() { }
};
int main()
{
Derived d;
Derived* ptr_derived = &d;
void *ptr_derived_void = ptr_derived;
Derived* ptr_derived_from_void = (Derived*)ptr_derived_void;
assert(ptr_derived_from_void == ptr_derived); //that's OK
Parent* ptr_parent = ptr_derived; //upcast
Parent* ptr_parent_from_void = (Parent*)ptr_derived_void; //upcast?
assert(ptr_parent_from_void == ptr_parent); //that's not OK
return 0;
}
这篇文章还显示了通过void*
投射的一些问题。
使用类A
和B
作为模板参数实例化的模板类涉及编译器创建两个单独的类来专门处理这些各自的类型。在许多方面,这就像一个智能强类型预处理器宏。手动复制粘贴两个分别对A
和B
进行操作的独立"正常"类没有什么不同。所以没有。
唯一的危险方法是,如果您尝试投射最初的内容:
MyClass<A>
如
MyClass<B>
如果A
不是 B
,因为它们可能具有不同的内存布局。
就是:指向数据的指针。指针的"类型"实际上对任何事情都没有区别(在编译时(,它只是为了代码的可读性和可维护性。
例如:
Foo<a> *x = new Foo<a>();
void *y = (void*)x;
Foo<a> *z = (Foo<a>*)y;
完全有效,不会引起任何问题。强制转换指针类型时的唯一问题是,当您忘记指针实际引用的基础数据类型时,可能会遇到取消引用问题。
如果你在任何地方传递 void*,只需注意保持类型完整性。
不要执行以下操作:
Foo<a> *x = new Foo<a>();
void *z = (void*)x;
//pass around z for a while, then mistakenly...
Foo<b> *y = (Foo<b>*)z;
意外!
- 为什么C++对链表中的下一个节点使用指针,而像 C# 或 Java 这样的语言只使用类 Node 的名称?
- 与其他语言相比的 Ruby 和指针
- 指针的一系列指针:管理不同语言的字符串
- 在闭包中,如何通过存储在内存中的指针或引用类型捕获可变性或用现代函数式语言进行处理?
- 我可以使用功能指针在编程语言边界上调用函数
- std::shared_ptr语言 - 将共享指针作为参数传递的最佳做法
- 在 C 语言中使用 *&*&p 了解复杂的指针和地址运算符
- C/C++语言-指针和算术..异常代码:c0000005
- 指向未指定大小的数组的指针在C++"(*p)[]"非法,但在 C 语言中是合法的
- 在 C 语言中旋转图像对象和指针
- c语言中的远函数指针是什么,它的语法是什么
- C++:在 C 语言中传递指向模板类的指针
- C或c++语言中的数组实际上是指针吗?
- c语言中具有指针数组的结构体
- 如何在c语言中将void*转换为float**,将void指针转换为float指针
- 段错误:C语言指针的地址越界
- C语言结构和指针的难点
- 如何在Java编程语言中添加指针
- std::vector语言 - 错误:无法删除不是指针的对象
- 在 C 语言中将浮点指针重新转换为双指针的最有效方法是什么?