类和动态内存分配

类和动态内存分配

整理自《C++ Primer Plus》

1. 动态内存和类

  • 静态类成员有一个特点:无论创建了多少对象,程序都只创建一个静态类变量副本。也就是说,类的所有对象共享同一个静态成员。静态数据成员在类声明中声明,在包含类方法的文件中初始化。
  • 复制构造函数用于将一个对象复制到新创建的对象中。也就是说,也就是说,它用于初始化过程中(包括按值传递参数),而不是常规的赋值过程中。按值传递意味着创建原始变量的一个副本。由于按值传递对象将调用复制构造函数,因此应该按引用传递对象。这样可以节省调用构造函数的时间以及存储新对象的空间。
    默认的复制构造函数逐个复制非静态成员(成员复制也被称为浅复制),复制的是成员的值。
    深度复制。必须定义复制构造函数的原因在于,一些类成员是使用new初始化的、指向数据的指针,而不是数据本身。

2. 在构造函数中使用new时应注意的事项

  • 如果在构造函数中使用new来初始化对象的指针成员时,则应在析构函数中使用delete。
  • new 和delete 必须相互兼容。new对应于delete, new[] 对应于delete[]。
  • 如果有多个构造函数,则必须以相同的方式使用new,要么都带中括号,要么都不带。
  • 应定义一个复制构造函数,通过深度复制将一个对象初始化为另一个对象。
  • 应当定义一个赋值运算符,通过深度复制将一个对象复制给另一个对象。该方法完成这些操作:检查自我赋值的情况,释放成员指针以前指向的内存,复制数据而不仅仅是数据的地址,并返回一个指向调用对象的引用。

3. 有关返回对象的说明

  • 返回指向const对象的引用
    使用const引用的常见原因是旨在提高效率,但对于何时可以采用这种方式存在一些限制。如果函数返回(通过调用对象的方法或将对象作为参数)传递给它的对象,可以通过返回引用来提高其效率。
Vector force1(50, 60);
Vector force2(10, 70);
Vector max;
max = Max(force1, force2);

// version1
Vector Max(const Vector & v1, const Vector & v2)
{
    if (v1.magval() > v2.magval())
        return v1;
    else
    {
        return v2;
    }
}

// version2

const Vector & Max(const Vector & v1, const Vector & v2)
{
    if (v1.magval() > v2.magval())
        return v1;
    else
    {
        return v2;
    }
}

说明:首先,返回对象将调用复制构造函数,而返回引用不会。因此,第二个版本所作的工作更少,效率更高。其次,引用指向的对象应该在调用函数执行时存在。第三,v1和v2都被声明为const引用,因此返回类型必须为const,这样才匹配。

  • 返回指向非const对象的引用。
    两种常见的返回非const对象情形是,重载赋值运算符以及重载与cout一起使用的<<运算符。
  • 返回对象
    如果被返回的对象是被调用函数中的局部变量,则不应按引用方式返回它,因为在被调用函数执行完毕时,局部对象将调用其析构函数。因此,当控制权回到调用函数时,引用指向的对象将不再存在。在这种情况下,应返回对象而不是引用。通常,被重载的算术运算符属于这一类。
  • 返回const对象
    总之,如果方法或函数要返回局部对象,则应返回对象,而不是指向对象的引用。在这种情况下,将使用复制构造函数来生成返回的对象。如果方法或函数要返回一个没有公有复制构造函数的类的对象,它必须返回一个指向这种对象的引用。最后,有些方法和函数(如重载的赋值运算符)可以返回对象,也可以返回指向对象的引用,在这种情况下,应首选引用,因为其效率更高。
  • 在下述情况下析构函数将被调用
    如果对象是动态变量,则当执行完定义该对象的程序块时,将调用该对象的析构函数。
    如果对象是静态变量(外部、静态、静态外部或来自名称空间),则在程序结束时调用对象的析构函数。
    如果对象是用new创建的,则仅当您显示使用delete删除对象时,其析构函数才会被调用。
  • 类方法
    对于const数据成员,必须在执行到构造函数体之前,即创建对象时进行初始化。C++提供了一种特殊的语法来完成上述工作,它叫做初始化成员列表。
    成员初始化列表由逗号分隔的初始化列表组成(前面带冒号)。它位于参数列表的右括号之后、函数体左括号之前。如果数据成员的名称为mdata,并需要将它初始化为val,则初始化器为mdata(val)。只有构造函数可以使用这种初始化列表语法。不能将成员初始化列表语法用于构造函数之外的其他类方法。

原文地址:https://www.cnblogs.com/adtxl/p/11494574.html

时间: 2024-10-11 05:09:37

类和动态内存分配的相关文章

C++ primer plus读书笔记——第12章 类和动态内存分配

第12章 类和动态内存分配 1. 静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域运算符来指出静态成员所属的类.但如果静态成员是整形或枚举型const,则可以在类声明中初始化. P426-P427类静态成员的声明和初始化 //strnbad.h class StringBad { private: static int num_strings; … }; //strnbad.cpp int StringBad::num_strings = 0; 不能在类声明中初始化静态

《C++ Primer Plus》读书笔记之十—类和动态内存分配

第12章 类和动态内存分配 1.不能在类声明中初始化静态成员变量,这是因为声明描述了如何分配内存,但并不分配内存.可以在类声明之外使用单独的语句进行初始化,这是因为静态类成员是单独存储的,而不是对象的组成部分.注意:静态成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域操作符来指出静态成员所属的类.但如果静态成员是整型或枚举型const,则可以在类声明中初始化. 2.当使用一个对象来初始化另一个新建对象时,编译器将自动生成一个复制构造函数,因为它创建对象的一个副本.复制构造函数的

C++-类和动态内存分配 大发彩_票平台开发

大发彩_票平台开发 地址一:[hubawl.com]狐霸源码论坛地址二:[bbscherry.com] 类和动态内存分配 动态内存和类 C++在分配内存时是让程序在运行时决定内存分配,而不是在编译时决定. 这样,可根据程序的需要,而不是根据一系列严格的存储类型规则来使用内存.C++使用new和delete运算符来动态控制内存. 1.1. 复习示例和静态类成员 这个程序使用了一个新的存储类型:静态类成员. //strngbad.h#include<iostream>#ifndef STRNGBA

C++ 学习笔记之---类和动态内存分配

参考自<C++ primer plus 6th edition> 请各位放大观看吧,感觉博客园的编辑器有点坑.用图片之后,又发现太小,所以... 程序对内存的使用: 链接:http://zhidao.baidu.com/link?url=An7QXTHSZF7zN9rAuY05mvaHHar0xIpgK6Yqp9oAkm2GmZYoTAz9UpN4JuhWJvSLsbu0-lOcO47PzXcNWda6gK 定义静态成员变量: 可以在类声明中定义静态成员变量,使用 static 修饰.不过,虽

《C++ Primer Plus》12.6 复习各种(类和动态内存分配的)技术 笔记

12.6.1 重载<<运算符要重新定义<<运算符,以便将它和cout一起用来显示对象的内容,请定义下面的友元运算符函数:ostream & operator<<(ostream & os, const c_name & obj){    os << ...;  // display object contents    return os;}其中,c_name是类名.如果该类提供了能够返回所需内容的公有方法,则可在运算符函数中使用这些

C++拾遗(十)类与动态内存分配(2)

静态成员函数 声明时包含关键字static.注意以下两点: 1.使用静态成员函数时不能通过对象或者this指针来调用,只能使用类名+作用域解析符来调用. 2.静态成员函数只能使用静态成员. new操作符 在使用 #include <new> 之后,new操作符可以在分配内存时指定内存位置.例如: 1 //创建一个512字节的内存缓冲区 2 char *buffer = new char[512]; 3 ClassName *ptr1, *ptr2; 4 5 //在buffer缓冲区中创建一个类

类与其动态内存分配

1. 类中的静态非常数数据( static , no const)需要在类外进行赋值,结构为 int class::varname = values ; 2. 类有五种特殊的函数类型: (1) 默认的构造函数 (2) 默认的析构函数 (3) 默认的复制构造函数 (4) 赋值运算函数 (5) 地址运算函数 (1): 默认的构造函数是一个没有参数,没有数据操作的函数 (2): 默认的复制构造函数是一个浅复制的函数,逐一复制非静态成员 (3): 默认的析构函数是一个没有任何操作的函数 (4): 默认的

动态内存分配类实现

今天学习了C++语言的内存动态分配,并借助所学的知识实现了一个动态内存分配类. 问题的背景为:在已经实现了一个点类的基础上,实现一个动态内存分配类,这个类 的功能为:实现根据输入的数目size,动态的生成size个点类对象:并在提供一个借口 可以对pos位置的对象进行操作:在对象生存期结束时,可以自动释放分配的内存空间. 根据描述的问题描述的需求,规划了如下的类图: 写出了一个包含三个方法的对点动态分配内存的类: 1: #ifndef _ARRAYOFPOINTS_H 2: #define _A

String类型_static成员_动态内存分配_拷贝构造函数_const关键字_友元函数与友元类

1:String类型 1 #include <iostream> 2 using namespace std; 3 int main() 4 { 5 //初始化方法 6 string s1 = "hello";//默认构造方法 7 string s2(s1);//将s2初始化为s1的一个副本 8 string s3("value");//将s3初始化为字符串的副本 9 string s4(10,'x');//将字符串初始化为字符x的10个副本 10 co