欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 游戏 > C++(数组,指针,深浅复制,nullptr与NULL)

C++(数组,指针,深浅复制,nullptr与NULL)

2024/10/24 17:19:37 来源:https://blog.csdn.net/qq_54094530/article/details/141069826  浏览:    关键词:C++(数组,指针,深浅复制,nullptr与NULL)

指针

对象指针

与指针的基本用法一样,声明对象指针的方式:类名 *对象指针名字

Point * PointPtr;    //声明Point类的对象指针变量PointPtr
Point pl;   //声明Point类的对象p1
PointPtr= &p1;  //将对象p1的地址赋给PointPtr,使PointPtr指向p1

使用对象指针来访问对象成员:对象指针名->成员名(与c语言中struct类似)

注:

在c++中其实struct和class都是用来定义类的,它们之间仅有的区别是struct定义的类成员默认公有(public),而class定义的类成员默认私有(private)

this指针:

      this指针是隐含于每一个类的非静态成员函数中的特殊指针(包含构造函数和析构函数),用于指向被成员函数操作的对象(由于类的静态函数不依赖于类的对象,属于类本身,因此不需要this指针)

     注:this指针是类成员函数的一个隐含参数(也就是此时类成员函数的参数数量是原有数量+1),目的对象的地址会自动作为this指针的值,this指针是一个普通指针,如果希望在函数内部不去修改对象的成员,你可以将 this 指针声明为指向常量对象的指针,即 const 成员函数。

vector创建数组对象:

vector<元素类型>数组对象名(数组长度);

int x= 10;   
vector<int>arr (x);  //大小为10的int型数组对象arr

此时arr是一个数组对象,而不是一个普通的数组,数组对象的操作都是模拟数组的操作来实现的

注:

       与普通数组不同的是,用vector定义的数组对象的所有元素都会被初始化。

       如果数组的元素类型为基本数据类型,则所有元素都会被以0初始化;

       如果数组元素为类类型,则会调用类的默认构造函数初始化。因此如果以此形式定义的vector动态数组,需要保证作为数组元素的类具有默认构造函数。另外,初值也可以自己指定,但只能为所有元素指定相同初值,形式为:

   vector<元素类型>数组对象名(数组长度,初值)

class MyClass {
public:MyClass(int value) : myValue(value) {}int getValue() const { return myValue; }private:int myValue;
};
vector<MyClass> myVector = {MyClass(1), MyClass(2), MyClass(3)};

深复制与浅复制:

    深复制与浅复制是两种不同的复制机制,它们之间的区别是在复制对象时是否复制其指向的资源

class MyClass {
public:MyClass() {}~MyClass() {}// 浅复制构造函数MyClass(const MyClass& other) : vec(other.vec) {}private:std::vector<std::string>* vec;
};int main() {MyClass original;original.vec.push_back("Hello");original.vec.push_back("World");MyClass copied = original; // 浅复制// 修改原始对象的 vec 中的一个元素original.vec[0] = "Hi";

     当使用浅复制来复制原对象vec时,我们修改原始对象的 vec 中的一个元素时,复制对象的 vec 中的对应元素也会被修改。

class MyClass {
public:MyClass() {}~MyClass() {}// 浅复制构造函数MyClass(const MyClass& other) : vec(other.vec) {}private:std::vector<std::string> vec;
};int main() {MyClass original;original.vec.push_back("Hello");original.vec.push_back("World");MyClass copied = original; // 深复制// 修改原始对象的 vec 中的一个元素original.vec[0] = "Hi";

      可以看到,其实这两个例子只是把指针换成了vector这个容器本身,但是如果我在堆上开空间,使用浅复制后调用析构函数(在堆上默认在构造函数开空间(new),析构函数释放空间(delete)),在释放时由于这两个对象都指向同一空间,那么会产生错误(二次释放空间)

c++风格的强制类型转换:

-------------cast类型转换符-----------------
static_cast:编译时类型转换,比较安全
const_cast:去const属性
dynamic_cast:运行时类型转换,主要用于类层次结构中的向下转型
            (一般从基类指针或引用转换为派生类指针时引用)
reinterpret_cast:底层类型转换,直接操作内存,功能强大,但是要考虑清楚(不会进行编译检查) 
                void*转int*
使用实例:reinterpret_cast<int *>

nullptr与NULL:

      NULL 是一个宏,通常定义为 (void*)0。这意味着 NULL 是一个指向 void 类型的指针。这可能会导致类型不匹配的错误,特别是在模板编程中。
      nullptr 是一个关键字,它表示一个没有指向任何对象的指针。它可以被编译器安全地用于任何指针类型,而不会导致类型不匹配的问题。

      nullptr的应用主要在对于指向对象时,NULL 是一个宏,通常定义为 (void*)0,如果将一个对象指针置为 NULL,编译器通常会发出警告,因为 NULL 不是指向对象的指针类型。但如果使用nullptr,编译器会推导出指针的类型。此时不会产生警告,且兼容性更高,因此,推荐使用nullptr

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com