Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;:在C中传递指向模板类的指针_C++_C_Templates_Wrapper - Fatal编程技术网

C++ C++;:在C中传递指向模板类的指针

C++ C++;:在C中传递指向模板类的指针,c++,c,templates,wrapper,C++,C,Templates,Wrapper,我正在为我的库编写一个C包装器API 在C.中,我通常将C++对象传递为 Value*/Cuff>,并且每个对象的公共函数都有自然访问包装功能。C代码不< /强>访问本机C++类成员。< /P> 昨天,有人提到IRC,我不应该把指针传递给C++模板类的指针,因为它是危险的。这是真的吗?从指针到模板类指针到普通C++类的指针有什么不同? 谢谢 这是假的。模板没有普通类不具备的特殊属性。确保始终使用适当的强制类型转换,您会很好。使用类A和B实例化的模板类,因为模板参数涉及编译器创建两个单独的类,专门

我正在为我的库编写一个C包装器API

在C.中,我通常将C++对象传递为<代码> Value*/Cuff>,并且每个对象的公共函数都有自然访问包装功能。C代码<强>不< /强>访问本机C++类成员。< /P>

昨天,有人提到IRC,我不应该把指针传递给C++模板类的指针,因为它是危险的。这是真的吗?从指针到模板类指针到普通C++类的指针有什么不同?


谢谢

这是假的。模板没有普通类不具备的特殊属性。确保始终使用适当的强制类型转换,您会很好。

使用类
A
B
实例化的模板类,因为模板参数涉及编译器创建两个单独的类,专门处理这些各自的类型。在许多方面,这就像一个智能的强类型预处理器宏。手动复制粘贴两个分别在
A
B
上操作的独立“正常”类并没有什么不同。所以没有

唯一危险的方法是,如果你试图施放原本是:

MyClass<A>
MyClass
作为

MyClass

如果
A
不是
B
,因为它们可能具有不同的内存布局。

这与模板与普通类无关,但是如果类具有多个继承,则在强制转换到
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<a> *x = new Foo<a>();
 void *y = (void*)x;
 Foo<a> *z = (Foo<a>*)y;
Foo*x=newfoo();
void*y=(void*)x;
Foo*z=(Foo*)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;
Foo*x=newfoo();
void*z=(void*)x;
//绕z转一圈,然后错误地。。。
Foo*y=(Foo*)z;

不小心

将一些指针
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;
}
#包括
班级家长
{
int-bar;
};
派生类:公共父类
{
虚拟void foo(){}
};
int main()
{
导出d;
派生*ptr_派生=&d;
void*ptr_-derived\u void=ptr_-derived;
派生*ptr\u派生自\u void=(派生*)ptr\u派生自\u void;
assert(ptr_-derived_-from_-void==ptr_-derived);//没问题
Parent*ptr\u Parent=ptr\u-derived;//上传
父*ptr\u父\u从\u void=(父*)ptr\u派生\u void;//上溯?
断言(ptr\u parent\u from\u void==ptr\u parent);//这不好
返回0;
}

此外,post还显示了通过
void*

强制转换的一些问题,您不应该将成员函数指针作为
void*
传递。或者函数指针,我想。此外,考虑使用强类型句柄(<代码> TyPulfStrut FooFo;FooCeCeaTyFixFor);ValueDebug YoFo(Foo*);< <代码> >,而不是<代码> Value*/Cord>。HM,强类型句柄可能更好,我将看看如何与我的包装代码匹配……纳瓦兹,你试过了吗?我用VS2010做的。无论是使用C风格的强制转换还是重新解释强制转换,都没有区别。严格来说,这不是真的。当涉及继承时,强制转换指针可能涉及调整内存中的值以指向超类或子类数据。但这与模板无关;这只是意味着你需要小心与适当的操作员铸造。
#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;
}