C++ 如何创建和使用unique_ptr实例
什么是C和C++编程语言中的实例
在C编程中,实例是对象或数据结构的单个出现。例如,如果你有一个名为”Dog”的类,那么你从这个类创建的每个狗都将是”Dog”类的一个实例。这意味着每个类实例都有自己的数据和由类定义的行为。
例如,你可以创建两个”Dog”类的实例,一个是名为”Fido”的狗,另一个是名为”Snoopy”的狗。这两个实例都有自己的特征,如它们的名字、年龄和品种,以及它们的行为,如能够叫或接球。
在C中,你可以使用new关键字创建类的实例,就像这样:
语法
Dog *fido = new Dog("Fido", 3, "Golden Retriever");
Dog *snoopy = new Dog("Snoopy", 5, "Beagle");
在这里,我们正在创建”Dog”类的两个实例,一个用于Fido,另一个用于Snoopy。每个实例都有其自己的数据集,例如其名称、年龄和品种,在创建实例时指定。
下面是一个示例,展示了如何在C中创建一个名为”Dog”的类,然后创建类的实例。
代码:
// Define the Dog class
class Dog {
public:
// Constructor to initialize the instance
Dog(string name, int age, string breed) {
this->name = name;
this->age = age;
this->breed = breed;
}
// Method to make the dog bark
void bark() {
cout << this->name << " says: Woof! Woof!" << endl;
}
private:
// Private data members
string name;
int age;
string breed;
};
int main() {
// Create two instances of the Dog class
Dog *fido = new Dog("Fido", 3, "Golden Retriever");
Dog *snoopy = new Dog("Snoopy", 5, "Beagle");
// Make the dogs bark
fido->bark();
snoopy->bark();
return 0;
}
在这个示例中,”Dog”类有一个构造函数,用于初始化每个类实例的数据。它还有一个”bark”方法,让狗叫。
在主函数中,我们创建了两个”Dog”类的实例,一个是Fido,另一个是Snoopy。然后我们在每个实例上调用bark方法,让狗叫。
当你运行这个程序时,应该会打印出以下输出。
输出:
Fido says Woof! Woof!
Snoopy says Woof! Woof!
C++实例
在C++中,实例是对象或数据结构的单个出现。例如,如果你有一个名为”Dog”的类,从该类创建的每只狗都是”Dog”类的一个实例。这意味着每个类实例都有由该类定义的一组自己的数据和行为。
例如,你可以创建”Dog”类的两个实例,一个为名为”Fido”的狗,另一个为名为”Snoopy”的狗。这两个实例都有自己的特征,如它们的名字、年龄和品种,以及它们的行为,如吠叫或接球的能力。
在C++中,你可以使用new关键字来创建类的实例,像这样:
Dog *fido = new Dog("Fido", 3, "Golden Retriever");
Dog *snoopy = new Dog("Snoopy", 5, "Beagle");
在这里,我们创建了两个”Dog”类的实例,一个用于Fido,另一个用于Snoopy。每个实例在创建时都指定了其数据集,例如名称、年龄和品种。
代码:
// Define the Person's class
class Person {
public:
// Constructor to initialize the instance
Person(string name, int age, string gender) {
this->name = name;
this->age = age;
this->gender = gender;
}
// Method to print the person's name and age
void printInfo() {
cout << "Name: " << this->name << ", Age: " << this->age << ", Gender: " << this->gender << endl;
}
private:
// Private data members
string name;
int age;
string gender;
};
// the main driver code functionality starts from here
int main() {
// Create two instances of the Person class
Person *john = new Person("John", 32, "Male");
Person *jane = new Person("Jane", 28, "Female");
// Print the person's information
john->printInfo();
jane->printInfo();
// the main driver code functionality ens from here
return 0;
}
在这个示例中,“Person”类有一个构造函数,用于初始化每个类实例的数据。它还有一个“printing”方法,用于打印人的姓名和年龄。
在主函数中,我们创建了两个“Person”类的实例,一个是John,另一个是Jane。然后我们调用每个实例上的printing方法来打印他们的信息。
当你运行这个程序时,它应该打印以下输出。
输出:
Name: John, Age: 32, Gender: Male
Name: Jane, Age: 28, Gender: Female
首先,指针是什么
在C和C++中,指针是一个变量,它保存了另一个变量的内存地址。指针通常引用在运行时动态分配的内存位置,例如在C中使用malloc函数或在C++中使用new操作符时。
指针很有用,因为它们允许您直接操作为程序分配的内存,从而更好地控制程序如何使用内存。例如,您可以使用指针访问和修改特定内存位置中的数据,或者创建比标准库提供的数据结构更高效、更灵活的数据结构。
其他语言没有指针的原因是因为使用指针可能很难使用,并且会使您的代码更难理解和维护。例如,不正确地使用指针可能导致内存泄漏或其他运行时错误,这些错误很难诊断和修复。此外,指针可以使您更难以推断代码的行为,因为指针的值可以在运行时动态更改。
然而,其他语言提供了类似的功能,允许您直接操作内存,例如C++中的引用或C#中的”unsafe”代码。这些功能在某些情况下很有用,但应谨慎使用,因为它们也可能引入指针可能引起的同样类型的问题。
C代码示例
#include
// The main driver code functionality starts from here
int main(void) {
int x = 10;
int *ptr = &x
printf("x = %d\n", x);
printf("ptr = %p\n", ptr);
printf("*ptr = %d\n", *ptr);
*ptr = 20;
printf("x = %d\n", x);
printf("ptr = %p\n", ptr);
printf("*ptr = %d\n", *ptr);
return 0;
// The main driver code functionality ends from here
}
输出:
x = 10
ptr = 0x7ffc1e1092ac
*ptr = 10
x = 20
ptr = 0x7ffc1e1092ac
*ptr = 20
C++ 代码
#include
// The main driver code functionality starts from here
int main(void) {
int x = 10;
int *ptr = &x
std::cout << "x = " << x << std::endl;
std::cout << "ptr = " << ptr << std::endl;
std::cout << "*ptr = " << *ptr << std::endl;
*ptr = 20;
std::cout << "x = " << x << std::endl;
std::cout << "ptr = " << ptr << std::endl;
std::cout << "*ptr = " << *ptr << std::endl;
return 0;
// The main driver functionality ends from here
}
输出:
x = 10
ptr = 0x7ffd1cfc1ebc
*ptr = 10
x = 20
ptr = 0x7ffd1cfc1ebc
*ptr = 20
在上面的示例中,ptr是指向int变量的指针。&运算符用于获取变量x的地址,*
运算符用于解引用指针并访问存储在该地址处的值。然后使用指针来修改x的值。
什么是智能指针
在C和C++中,智能指针是一个表现类似指针的对象,但具有额外功能,有助于管理所指向对象的生命周期。智能指针在不再需要时可以自动删除对象并防止内存泄漏。
以下是C++中智能指针的示例:
#include
#include
int main()
{
// Create a new integer and store its address in a smart pointer
std::unique_ptr ptr(new int(5));
// Access the integer value through the smart pointer
std::cout << *ptr << std::endl;
return 0;
}
输出:
5
解释:
这段代码将创建一个值为5的新整数对象,并将其地址存储在unique_ptr中。然后,使用unique_ptr访问整数的值,并将其打印到控制台。
由于unique_ptr管理所指向对象的生命周期,当unique_ptr在main函数结束时超出范围时,整数对象将被自动删除。这有助于防止内存泄漏。
请注意,C++中有几种不同类型的智能指针,每种都具有特定的行为。unique_ptr只是其中一种示例。其他常见类型的智能指针包括shared_ptr和weak_ptr。
为什么C语言中没有智能指针的支持呢
智能指针是C++的一项功能,而不是C的一部分。在C++中,智能指针是一个包装原始指针并管理原始指针所指对象生命周期的对象。智能指针在超出范围时自动删除它们所指向的对象,从而有助于防止内存泄漏。
为什么C编程语言中没有unique_ptr
unique_ptr不是C语言的一部分。unique_ptr是C++编程语言中可用的一种智能指针类型。智能指针是一种像普通指针一样的对象,但还具有自动内存管理和边界检查等附加功能。
unique_ptr是一种拥有并管理所指对象的智能指针。这意味着unique_ptr负责为其所指对象分配和释放内存,并且它是唯一可以访问或修改该内存的对象。unique_ptr提供了一种安全高效地管理动态分配内存的方法,通常用作C++中原始指针的替代品。
在C++中的unique_ptr
std::unique_ptr是一种智能指针,用于管理动态分配对象的生命周期。它确保当unique_ptr超出范围时,该对象被正确地删除,并通过其->
和*
操作符访问对象的方法。
以下是创建和使用unique_ptr的示例。
示例1:
#include
#include
// The main driver code functionality starts from here
int main() {
// Create a unique_ptr that points to a new int with the value 5.
std::unique_ptr ptr1(new int(5));
// Use the -> and * operators to manipulate the object that the unique_ptr points to.
std::cout << *ptr1 << std::endl; // Outputs 5
*ptr1 = 6;
std::cout << *ptr1 << std::endl; // Outputs 6
// Transfer ownership of the object to a new unique_ptr.
std::unique_ptr ptr2 = std::move(ptr1);
// The original unique_ptr no longer points to the object.
std::cout << (ptr1 ? "true" : "false") << std::endl; // Outputs "false"
// The new unique_ptr now owns the object and can manipulate it.
std::cout << *ptr2 << std::endl; // Outputs 6
*ptr2 = 7;
std::cout << *ptr2 << std::endl; // Outputs 7
return 0;
// The main driver code functionality ends from here
}
输出:
5
6
false
6
7
解释:
在这个示例中,我们创建了一个指向动态分配的整数值为5的unique_ptr,名为ptr1。我们使用->
和*
运算符来访问和操作ptr1指向的对象。
接下来,我们使用std::move函数将对象的所有权转移给了一个新的unique_ptr,名为ptr2。这意味着ptr1不再指向该对象。
示例2
#include
#include
// The main driver code functionality starts from here
int main() {
std::unique_ptr ptr(new int(10));
std::cout << "ptr = " << ptr.get() << std::endl;
std::cout << "*ptr = " << *ptr << std::endl;
*ptr = 20;
std::cout << "ptr = " << ptr.get() << std::endl;
std::cout << "*ptr = " << *ptr << std::endl;
return 0;
// The main driver code functionality ends from here
}
输出:
ptr = 0x55d09d214eb0
*ptr = 10
ptr = 0x55d09d214eb0
*ptr = 20
示例3
#include
#include // for std::unique_ptr
// A simple class with a constructor and a destructor
class MyClass
{
public:
MyClass() { std::cout << "MyClass constructed\n"; }
~MyClass() { std::cout << "MyClass destructed\n"; }
};
int main()
{
// Create a unique pointer to a MyClass object
std::unique_ptr ptr(new MyClass());
// ptr goes out of scope here, and the object pointed to by ptr
// is automatically deleted because of the unique_ptr
}
输出:
MyClass constructed
MyClass destructed