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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值