我正在使用一个C库,该库使用来自C ++的原始指针。因此,我正在研究将指向C对象的所有指针包装在C ++类中,并将它们转换为智能指针。我建立了一个工作示例:
#include <iostream>
using namespace std;
// the C library is oop: using structs and naming conventions. Like this:
// C library declarations
struct Animal_s {
int age;
};
typedef struct Animal_s Animal;
Animal* make_animal(int age);
void free_animal(Animal* animal);
Animal* do_something_with_animal(Animal* animal);
// C lib implementations
Animal* make_animal(int age ){
auto* animal = (Animal*) malloc(sizeof(Animal));
animal->age = age;
return animal;
}
void free_animal(Animal *animal){
free(animal);
}
Animal* do_something_with_animal(Animal* animal){
//...
return animal;
}
// C++ wrapper
class AnimalWrapper{
Animal* animal_; // how to use smart pointers?
public:
explicit AnimalWrapper(int age){
animal_ = make_animal(age);
};
~AnimalWrapper(){
free_animal(animal_);
}
AnimalWrapper(const AnimalWrapper& animalWrapper){
if (this != &animalWrapper){
animal_ = animalWrapper.animal_;
}
}
AnimalWrapper(AnimalWrapper&& animalWrapper) noexcept {
if (this != &animalWrapper){
animal_ = animalWrapper.animal_;
}
}
AnimalWrapper& operator=(const AnimalWrapper& animalWrapper) {
if (this != &animalWrapper){
animal_ = animalWrapper.animal_;
}
return *this;
}
AnimalWrapper& operator=(AnimalWrapper&& animalWrapper) noexcept {
if (this != &animalWrapper){
animal_ = animalWrapper.animal_;
}
return *this;
}
Animal *getAnimal() const {
return animal_;
}
Animal* doSomethingWithAnimal(){
return do_something_with_animal(animal_);
}
};
int main(){
AnimalWrapper animalWrapper(6);
return 0;
};
此示例有效,并且根据valgrind,正确管理内存。但是,是否可以使用智能指针来实现包装类?还是必须手动管理包装器类中的内存?
您不能在C中使用任何C ++问题。您正在做的是将C代码与C ++编译器一起使用,因为C不支持类似的东西
using namespace something;
通常,如果将指针传递给尚未声明为extern "C"
的内容,则会遇到麻烦。
您对C ++使用C构造感到非常困惑。如果声明struct A
,则不需要typedef struct A A;
,因为C ++中隐含了该内容。但这不能是C,因为您在源代码中使用了use namespace
...。
要在代码中使用C库,您需要声明(仅在C ++中)为extern "C"
,否则链接器在查找它时会遇到严重的麻烦(由于C ++对标识符进行名称修改以支持重载)
我猜你在这种情况下不能获得完整的汇编。
您可以使用std::unique_ptr
管理Animal
对象的生存期: