Error[8]: Undefined offset: 860, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

类和动态内存分配


动态内存和类 静态类成员 特殊成员函数

C++自动提供了下面这些成员函数:

编译器将生成上述最后三个函数的定义——如果程序使用对象的方式要求这样做。

例如,如果您将一个对象赋给另一个对象,编译器将提供赋值运算符的定义。

C++11提供了另外两个特殊成员函数:移动构造函数(move constructor)和移动赋值运算符(move assignment operator),这两个将在后面进行详细讨论。

string类的改进

这一节主要是举了几个例子,增加了几个string类的功能。

具体地说,将添加以下方法:

int length() const {return len;}
friend bool operator<(const String &st, const String &st2);
friend bool operator>(const String &st1, const String &st2);
friend bool operator==(const String &st, const String &st2);
friend bool operator>>(istream & is, String &st);
char & operator[](int i);
const char & operator[](int i) const;
static int HowMany();

string.h

#ifndef STRING_H_
#define STRING_H_
#include 
using std::ostream;
using std::istream;

class String
{
private:
	char * str;   			// pointer to string
	int len;	  			// length of string
	static int num_strings; // number of objects
	static const int CINLIM = 80; // cin input limit
public:
	// constructors and other methods
	String(const char * s);  // constructor
	String();				 // default constructor
	String(const String &);	 // copy constructor
	~String();				 // destructor
	int length() const {return len;}
	// overloaded operator methods
	String & operator=(const String &);
	String & operator=(const char *);
	char & operator[](int i);
	const char & operator[](int i) const;
	// overloaded operator friends
	/*
	将比较函数作为友元,有助于将String对象与常规的C字符串进行比较。

**这个地方需要一个具体的例子再说明一下成员函数和友元的区别!** */ friend bool operator<(const String &st, const String &st2); friend bool operator>(const String &st1, const String &st2); friend bool operator==(const String &st, const String &st2); friend istream & operator<<(ostream & os, const String & st); friend istream & operator>>(istream & is, String & st); // static function static int HowMany(); }; #endif

string.cpp

#include 
#include "string.h"
using std::cin;
using std::cout;

//initializing static class member
int String::num_strings = 0;  // 初始化静态变量

//static method
/*
1. 首先,不能通过对象调用静态成员函数;实际上,静态成员函数甚至不能使用this指针。

如果静态成员函数是在共有部分声明的,则可以使用类名和作用域解析运算符来调用它。

调用方式: int count = String::HowMany(); 2. 其次,由于静态成员函数不与特定的对象相关联,因此只能使用静态数据成员。

*/ int String::HowMany() { return num_strings; } //class methods String::String(const char * s) // construct String from C string { len = std::strlen(s); // set size str = new char[len + 1]; // allot storage std::strcpy(str, s); // initialize pointer num_strings++; // set object count } String::String() // default constructor { len = 4; str = new char[1]; str[0] = ';'// default string ++ num_strings;} String ::String(const& String ) st++ { num_strings;// handle static member update = len . st;len// same length = str new char [+len 1 ];// allot space :: stdstrcpy(,str. st)str;// copy string to new location } String ::~String()// necessary destructor -- { ;num_strings// required delete [ ]; str// required } //overloaded operator methods // assign a String to a String & String :: Stringoperator=(const& String ) stif { ( this== & )streturn * this;delete [ ]; str= len . st;len= str new char [+len 1 ];:: stdstrcpy(,str. st)str;return * this;} //assign a C string to a string & String :: Stringoperator=(charcosnt * ) sdelete { [ ]; str= len :: stdstrlen()s;= str new char [+len 1 ];:: stdstrcpy(,str) s;return * this;} //read-write char access for non-const string char & :: Stringoperator[](int) ireturn { [ str]i;} //read-only char access for const String const char & :: Stringoperator[](int) iconst return { [ str]i;} //overloaded operator friends bool /* 要实现字符串比较函数,最简单的方法是使用标准的strcmp()函数, 如果依照字母顺序,第一个参数位于第二个参数之前,则该函数返回一个负值; 如果两个字符串相同,则返回0; 如果第一个参数位于第二个参数之后,则返回一个正值。

*/ operator <(const& String ,st1const & String )st2return { ( ::stdstrcmp(.st1,str. st2)str< 0 );} bool operator (>const& String ,st1const & String )st2return { < st2 ; st1} bool operator ==(const& String ,st1const & String )st2return { ( ::stdstrcmp(.st2,str. st1)str== 0 );} //simple String output & ostream operator <<(&ostream , osconst & String ) st<< { os . st;strreturn ; os} //quick and dirty String input & istream operator (>>&istream , is& String ) stchar { [ temp::String]CINLIM;. isget(,temp:: String)CINLIM;if ()is= st ; tempwhile (&&is . isget()!= '\n' )continue ;return ; is} new

构造函数中的new 返回对象 指向对象的指针 成员初始化列表(member initializer list)

如果mem2是一个类,而mem3, Classy, ::都是这个类的数据成员,则类构造函数可以使用如下的语法来初始化数据成员:

Classy(int,int n) : mmem1( ),nmem2( 0),mem3( *+n2m)//···}
{
	mem1
n

上述代码将mem2初始化为0,将mem3初始化为n*m+2,将

  • 只有构造函数可以使用这种初始化列表语法;
  • 初始化为const

    从概念上说,这些初始化工作是在对象创建时完成的,此时还未执行括号中的任何代码。

    请注意以下几点:

    数据成员被初始化的顺序与它们出现在类声明中的顺序相同,与初始化器中的排列顺序无关。

    警告:不能将成员初始化列表语法用于构造函数之外的其他类方法。

    )
    File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
    File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 165, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
    File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
    Error[8]: Undefined offset: 861, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
    File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

    类和动态内存分配


    动态内存和类 静态类成员 特殊成员函数

    C++自动提供了下面这些成员函数:

    编译器将生成上述最后三个函数的定义——如果程序使用对象的方式要求这样做。

    例如,如果您将一个对象赋给另一个对象,编译器将提供赋值运算符的定义。

    C++11提供了另外两个特殊成员函数:移动构造函数(move constructor)和移动赋值运算符(move assignment operator),这两个将在后面进行详细讨论。

    string类的改进

    这一节主要是举了几个例子,增加了几个string类的功能。

    具体地说,将添加以下方法:

    int length() const {return len;}
    friend bool operator<(const String &st, const String &st2);
    friend bool operator>(const String &st1, const String &st2);
    friend bool operator==(const String &st, const String &st2);
    friend bool operator>>(istream & is, String &st);
    char & operator[](int i);
    const char & operator[](int i) const;
    static int HowMany();
    

    string.h

    #ifndef STRING_H_
    #define STRING_H_
    #include 
    using std::ostream;
    using std::istream;
    
    class String
    {
    private:
    	char * str;   			// pointer to string
    	int len;	  			// length of string
    	static int num_strings; // number of objects
    	static const int CINLIM = 80; // cin input limit
    public:
    	// constructors and other methods
    	String(const char * s);  // constructor
    	String();				 // default constructor
    	String(const String &);	 // copy constructor
    	~String();				 // destructor
    	int length() const {return len;}
    	// overloaded operator methods
    	String & operator=(const String &);
    	String & operator=(const char *);
    	char & operator[](int i);
    	const char & operator[](int i) const;
    	// overloaded operator friends
    	/*
    	将比较函数作为友元,有助于将String对象与常规的C字符串进行比较。

    **这个地方需要一个具体的例子再说明一下成员函数和友元的区别!** */ friend bool operator<(const String &st, const String &st2); friend bool operator>(const String &st1, const String &st2); friend bool operator==(const String &st, const String &st2); friend istream & operator<<(ostream & os, const String & st); friend istream & operator>>(istream & is, String & st); // static function static int HowMany(); }; #endif

    string.cpp

    #include 
    #include "string.h"
    using std::cin;
    using std::cout;
    
    //initializing static class member
    int String::num_strings = 0;  // 初始化静态变量
    
    //static method
    /*
    1. 首先,不能通过对象调用静态成员函数;实际上,静态成员函数甚至不能使用this指针。

    如果静态成员函数是在共有部分声明的,则可以使用类名和作用域解析运算符来调用它。

    调用方式: int count = String::HowMany(); 2. 其次,由于静态成员函数不与特定的对象相关联,因此只能使用静态数据成员。

    */ int String::HowMany() { return num_strings; } //class methods String::String(const char * s) // construct String from C string { len = std::strlen(s); // set size str = new char[len + 1]; // allot storage std::strcpy(str, s); // initialize pointer num_strings++; // set object count } String::String() // default constructor { len = 4; str = new char[1]; str[0] = ';'// default string ++ num_strings;} String ::String(const& String ) st++ { num_strings;// handle static member update = len . st;len// same length = str new char [+len 1 ];// allot space :: stdstrcpy(,str. st)str;// copy string to new location } String ::~String()// necessary destructor -- { ;num_strings// required delete [ ]; str// required } //overloaded operator methods // assign a String to a String & String :: Stringoperator=(const& String ) stif { ( this== & )streturn * this;delete [ ]; str= len . st;len= str new char [+len 1 ];:: stdstrcpy(,str. st)str;return * this;} //assign a C string to a string & String :: Stringoperator=(charcosnt * ) sdelete { [ ]; str= len :: stdstrlen()s;= str new char [+len 1 ];:: stdstrcpy(,str) s;return * this;} //read-write char access for non-const string char & :: Stringoperator[](int) ireturn { [ str]i;} //read-only char access for const String const char & :: Stringoperator[](int) iconst return { [ str]i;} //overloaded operator friends bool /* 要实现字符串比较函数,最简单的方法是使用标准的strcmp()函数, 如果依照字母顺序,第一个参数位于第二个参数之前,则该函数返回一个负值; 如果两个字符串相同,则返回0; 如果第一个参数位于第二个参数之后,则返回一个正值。

    */ operator <(const& String ,st1const & String )st2return { ( ::stdstrcmp(.st1,str. st2)str< 0 );} bool operator (>const& String ,st1const & String )st2return { < st2 ; st1} bool operator ==(const& String ,st1const & String )st2return { ( ::stdstrcmp(.st2,str. st1)str== 0 );} //simple String output & ostream operator <<(&ostream , osconst & String ) st<< { os . st;strreturn ; os} //quick and dirty String input & istream operator (>>&istream , is& String ) stchar { [ temp::String]CINLIM;. isget(,temp:: String)CINLIM;if ()is= st ; tempwhile (&&is . isget()!= '\n' )continue ;return ; is} new

    构造函数中的new 返回对象 指向对象的指针 成员初始化列表(member initializer list)

    如果mem2是一个类,而mem3, Classy, ::都是这个类的数据成员,则类构造函数可以使用如下的语法来初始化数据成员:

    Classy(int,int n) : mmem1( ),nmem2( 0),mem3( *+n2m)//···}
    {
    	mem1
    n
    

    上述代码将mem2初始化为0,将mem3初始化为n*m+2,将

  • 只有构造函数可以使用这种初始化列表语法;
  • 初始化为const

    从概念上说,这些初始化工作是在对象创建时完成的,此时还未执行括号中的任何代码。

    请注意以下几点:

    数据成员被初始化的顺序与它们出现在类声明中的顺序相同,与初始化器中的排列顺序无关。

    警告:不能将成员初始化列表语法用于构造函数之外的其他类方法。

    )
    File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
    File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 165, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
    File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
    C++ Primer Plus学习(十一)——类和动态内存分配_C_内存溢出

    C++ Primer Plus学习(十一)——类和动态内存分配

    C++ Primer Plus学习(十一)——类和动态内存分配,第1张

    类和动态内存分配
    • 动态内存和类
      • 静态类成员
      • 特殊成员函数
    • string类的改进
    • 构造函数中的new
    • 返回对象
    • 指向对象的指针
    • 成员初始化列表(member initializer list)


    动态内存和类 静态类成员
    • 静态类成员有一个特点:无论创建了多少对象,程序都只创建一个静态类变量副本。

      也就是说,类的所有对象共享同一个静态成员,就像家中的电话可供全体家庭成员共享一样。

    • 不能在类声明中初始化静态成员变量,这是因为声明描述了如何分配内存,但并不分配内存。

      对于静态类成员,可以在类声明之外使用单独的语句来进行初始化,这是因为静态类成员是单独存储的,而不是对象的组成部分。

    • 对于不能在类声明中初始化静态数据成员的一种类外情况是,静态数据成员为const整数类型或枚举型。

    • 总之,静态数据成员在类声明中声明,在包含类方法的文件中初始化。

      初始化时使用作用域运算符来指出静态成员所属的类。

      但如果静态成员是const整数类型或枚举型,则可以在类声明中初始化。

    特殊成员函数

    C++自动提供了下面这些成员函数:

    • 默认构造函数,如果没有定义构造函数;

      如果没有提供任何构造函数,C++将创建默认构造函数,也就是说,编译器将提供一个不接受任何参数,也不执行任何 *** 作的构造函数(默认的默认构造函数),这是因为创建对象时总是会调用构造函数;

      带参数的构造函数也可以是默认构造函数,只要所有参数都有默认值。

    • 默认析构函数,如果没有定义;

      如果没有提供任何析构函数,C++将创建默认析构函数。

      默认析构函数不执行任何 *** 作,这里不展开讨论。

    • 复制构造函数,如果没有定义;

      1. 复制构造函数用于将一个对象复制到新创建的对象中,也就是说,它用于初始化过程中。

        具体地说就是,新建一个对象并将其初始化为同类现有对象时,复制构造函数都将被调用。

      2. 还有每当程序生成了对象副本时,编译器都将使用复制构造函数。

        具体地说,当函数按值传递对象或函数返回对象时,都将使用复制构造函数。

        记住,按值传递意味着创建原始变量的一个副本,编译器生成临时对象时,也将使用复制构造函数。

      3. 默认的复制构造函数逐个复制非静态成员(成员复制也称为浅复制),复制的是成员的值。

      4. 如果类中包含静态数据成员,即其值将在新对象被创建时发生变化,则应该提供一个显式复制构造函数来处理计数等问题。

        原因在于隐式复制构造函数是按值进行复制的。

        另外,如果遇到指针,按值复制只能复制一个指针,也就是一个地址,这就导致不同对象共用一个指针,释放的时候会导致同一块内存被释放两次,从而导致程序异常终止。

      5. 解决这种问题的方法是进行深度复制(deep copy),也就是说,复制构造函数应当复制字符串并将副本的地址赋给新的对象成员,而不仅仅是复制字符串地址。

        总之,如果类中包含了使用new初始化的指针成员,应当定义一个复制构造函数,以复制指向的数据,而不是指针,这被称为深度复制。

        复制的另一种形式(成员复制或浅复制)只是复制指针值。

    • 赋值运算符,如果没有定义;

      将已有的对象赋给另一个对象时,将使用重载的赋值运算符。

      针对对象使用赋值运算符时,会分两步来进行处理:使用复制构造函数创建一个临时对象,然后通过赋值将临时对象的值复制到新对象中。

      和复制构造函数相同,也会有成员复制等问题;解决办法就是提供赋值运算符(进行深度复制)定义。

      其实现与复制构造函数相似,但也有一些差别:

      1. 由于目标对象可能引用了以前分配的数据,所以函数应使用delete[]来释放这些数据;
      2. 函数应当避免将对象赋给自身;否则,给对象重新赋值前,释放内存 *** 作可能删除对象的内容;
      3. 函数返回一个指向调用对象的引用。

    • 地址运算符,如果没有定义。

      隐式地址运算符返回调用对象的地址(即this指针的值),符合我们的初衷,不需要展开讨论。

    编译器将生成上述最后三个函数的定义——如果程序使用对象的方式要求这样做。

    例如,如果您将一个对象赋给另一个对象,编译器将提供赋值运算符的定义。

    C++11提供了另外两个特殊成员函数:移动构造函数(move constructor)和移动赋值运算符(move assignment operator),这两个将在后面进行详细讨论。

    string类的改进

    这一节主要是举了几个例子,增加了几个string类的功能。

    具体地说,将添加以下方法:

    int length() const {return len;}
    friend bool operator<(const String &st, const String &st2);
    friend bool operator>(const String &st1, const String &st2);
    friend bool operator==(const String &st, const String &st2);
    friend bool operator>>(istream & is, String &st);
    char & operator[](int i);
    const char & operator[](int i) const;
    static int HowMany();
    

    string.h

    #ifndef STRING_H_
    #define STRING_H_
    #include 
    using std::ostream;
    using std::istream;
    
    class String
    {
    private:
    	char * str;   			// pointer to string
    	int len;	  			// length of string
    	static int num_strings; // number of objects
    	static const int CINLIM = 80; // cin input limit
    public:
    	// constructors and other methods
    	String(const char * s);  // constructor
    	String();				 // default constructor
    	String(const String &);	 // copy constructor
    	~String();				 // destructor
    	int length() const {return len;}
    	// overloaded operator methods
    	String & operator=(const String &);
    	String & operator=(const char *);
    	char & operator[](int i);
    	const char & operator[](int i) const;
    	// overloaded operator friends
    	/*
    	将比较函数作为友元,有助于将String对象与常规的C字符串进行比较。

    **这个地方需要一个具体的例子再说明一下成员函数和友元的区别!** */ friend bool operator<(const String &st, const String &st2); friend bool operator>(const String &st1, const String &st2); friend bool operator==(const String &st, const String &st2); friend istream & operator<<(ostream & os, const String & st); friend istream & operator>>(istream & is, String & st); // static function static int HowMany(); }; #endif

    string.cpp

    #include 
    #include "string.h"
    using std::cin;
    using std::cout;
    
    //initializing static class member
    int String::num_strings = 0;  // 初始化静态变量
    
    //static method
    /*
    1. 首先,不能通过对象调用静态成员函数;实际上,静态成员函数甚至不能使用this指针。

    如果静态成员函数是在共有部分声明的,则可以使用类名和作用域解析运算符来调用它。

    调用方式: int count = String::HowMany(); 2. 其次,由于静态成员函数不与特定的对象相关联,因此只能使用静态数据成员。

    */ int String::HowMany() { return num_strings; } //class methods String::String(const char * s) // construct String from C string { len = std::strlen(s); // set size str = new char[len + 1]; // allot storage std::strcpy(str, s); // initialize pointer num_strings++; // set object count } String::String() // default constructor { len = 4; str = new char[1]; str[0] = ';'// default string ++ num_strings;} String ::String(const& String ) st++ { num_strings;// handle static member update = len . st;len// same length = str new char [+len 1 ];// allot space :: stdstrcpy(,str. st)str;// copy string to new location } String ::~String()// necessary destructor -- { ;num_strings// required delete [ ]; str// required } //overloaded operator methods // assign a String to a String & String :: Stringoperator=(const& String ) stif { ( this== & )streturn * this;delete [ ]; str= len . st;len= str new char [+len 1 ];:: stdstrcpy(,str. st)str;return * this;} //assign a C string to a string & String :: Stringoperator=(charcosnt * ) sdelete { [ ]; str= len :: stdstrlen()s;= str new char [+len 1 ];:: stdstrcpy(,str) s;return * this;} //read-write char access for non-const string char & :: Stringoperator[](int) ireturn { [ str]i;} //read-only char access for const String const char & :: Stringoperator[](int) iconst return { [ str]i;} //overloaded operator friends bool /* 要实现字符串比较函数,最简单的方法是使用标准的strcmp()函数, 如果依照字母顺序,第一个参数位于第二个参数之前,则该函数返回一个负值; 如果两个字符串相同,则返回0; 如果第一个参数位于第二个参数之后,则返回一个正值。

    */ operator <(const& String ,st1const & String )st2return { ( ::stdstrcmp(.st1,str. st2)str< 0 );} bool operator (>const& String ,st1const & String )st2return { < st2 ; st1} bool operator ==(const& String ,st1const & String )st2return { ( ::stdstrcmp(.st2,str. st1)str== 0 );} //simple String output & ostream operator <<(&ostream , osconst & String ) st<< { os . st;strreturn ; os} //quick and dirty String input & istream operator (>>&istream , is& String ) stchar { [ temp::String]CINLIM;. isget(,temp:: String)CINLIM;if ()is= st ; tempwhile (&&is . isget()!= '\n' )continue ;return ; is} new

    构造函数中的new
    • 在构造函数中使用delete来分配内存时,必须在相应的析构函数中使用new[]来释放内存。

      如果使用delete[](包括中括号)来分配内存,则应使用new(包括中括号)来释放内存。

    • 如果有多个构造函数,则必须以相同的方式使用new,要么都带中括号,要么都不带。

      因为只有一个析构函数,所有的构造函数都必须与它兼容。

      然而,可以在一个构造函数中使用 nullptr初始化指针,而在另一个构造函数中将指针初始化为空(0或C++11中的delete),这是因为delete(无论是带中括号还是不带中括号)可以用于空指针。

      (也就是说,如果析构函数通过对指针类成员使用new来释放内存,则每个构造函数都应当使用NULL来初始化指针,或将它设置为空指针。

      0nullptr还是0:以前,空指针可以用NULLNULL(在很多头文件中,0是一个被定义为NULL的符号常量)来表示。

      C程序员通常使用0而不是'0',以指出这是一个指针,就像使用0而不是NULL来表示空字符,以指出这是一个字符一样。

      然而,C++传统上更喜欢用简单的nullptr,而不是等价的String

      但正如前面指出的,C++11提供了关键字::,这是一种更好选择。

    • 应定义一个复制构造函数,通过深度复制将一个对象初始化为另一个对象。

      通常,这种构造函数与下面类似。

      String(const&) String ++ st;
      {
      	num_strings// handle static member update= 				.
      	len ; st// same lengthlen=				new
      	str char [ +1len ] ;// allot space::	strcpy
      	std(,.str) st;str// copy string to new location}	&
      ::
      

      具体地说,复制构造函数应该分配足够的空间来存储复制的数据,并复制数据,而不仅仅是数据的地址。

      另外,还应该更新所有受影响的静态类成员。

    • 应当定义一个赋值运算符,通过深度复制讲一个对象复制给另一个对象。

      通常,该类方法与下面类似:

      String operator String=(const&) String if st(
      {
      	this ==& ) // object assigned to itselfstreturn			*
      		this ;// all donedelete           [
      	] ;// free old string str=				.
      	len ; st=lennew				
      	str char [ +1len ] ;// get space for new string::	strcpy
      	std(,.str) st;str// copy the stringreturn	*
      	this ;// return reference to invoking object}				// use pointers to keep track of shortest, first strings
      // sayings是一个数组,元素为字符串(谚语);shortest指向最短的,first指向按字母顺序排在最前面的	
      
    返回对象
    • 如果方法或函数要返回局部对象,则应返回对象,而不是指向对象的引用,因为在被调用函数执行完毕时,局部对象将调用其析构函数。

      因此,当控制权回到调用函数时,引用指向的对象将不再存在。

      在这种情况下,将使用复制构造函数来生成返回的对象。

    • 如果方法或函数要返回一个没有公有复制构造函数的类(如ostream类)的对象,它必须返回一个指向这种对象的引用。

    • 最后,有些方法和函数(如重载的赋值运算符)可以返回对象,也可以返回指向对象的引用,在这种情况下,应首选引用,因为其效率更高。

      比如,如果函数返回(通过调用对象的方法或将对象作为参数)传递给它的对象,可以通过返回引用来提高效率。

    • 总之,返回对象将调用复制构造函数,而返回引用不会。

      所以返回引用所做的工作更少,效率更高。

      其次,引用指向的对象应该在调用函数执行时存在。

      另外,如果引用被声明为const引用,则返回类型必须为const,这样才匹配。

    指向对象的指针
    • 先举个例子感受一下用指针来跟踪对象(可以用于在对象数组中挑选符合条件的对象):

      *
      =
      String & shortest [ 0sayings];// initialize to first object*   =
      String & first [ 0sayings];for(
      int=1 i ; <; i ++ total) iif(
      {
      	[]sayings.ilength()<length ( shortest->))=&
      		shortest [ ]sayings;iif(
      	[]sayings<i* ) =first&
      		first [ ]sayings;i}new
      delete
      
    • 析构函数将被调用的情形:

      • 如果对象是动态变量,则当执行完定义该对象的程序块时,将调用该对象的析构函数。

      • 如果对象是静态变量(外部、静态、静态外部或来自名称空间),则在程序结束时将调用对象的析构函数。

      • 如果对象是String * glamour;创建的,则仅当您显式使用String * first = &sayings[0];删除对象时,其析构函数才会被调用。

    • 使用对象指针时,需要注意几点:

      • 使用常规表示法来声明指向对象的指针:
        new
      • 可以将指针初始化为指向已有的对象:
        String * favorite = new String(sayings[choice]);
      • 可以使用new来初始化指针,这将创建一个新的对象:
        (*)
      • 对类使用Classy将调用相应的类构造函数来初始化新创建的对象
      • 可以使用->运算符通过指针访问类方法
      • 可以对对象指针应用解除引用运算符mem1来获取对象
    成员初始化列表(member initializer list)

    如果mem2是一个类,而mem3, Classy, ::都是这个类的数据成员,则类构造函数可以使用如下的语法来初始化数据成员:

    Classy(int,int n) : mmem1( ),nmem2( 0),mem3( *+n2m)//···}
    {
    	mem1
    n
    

    上述代码将mem2初始化为0,将mem3初始化为n*m+2,将

  • 只有构造函数可以使用这种初始化列表语法;
  • 初始化为const

    从概念上说,这些初始化工作是在对象创建时完成的,此时还未执行括号中的任何代码。

    请注意以下几点:

      const
    • 对于const类成员,必须使用这种语法(必须用这种格式来初始化非静态数据成员);
    • 对于被声明为引用的类成员,也必须使用这种语法,这是因为引用和数据类似,只能在被创建时进行初始化。

    数据成员被初始化的顺序与它们出现在类声明中的顺序相同,与初始化器中的排列顺序无关。

    警告:不能将成员初始化列表语法用于构造函数之外的其他类方法。

    欢迎分享,转载请注明来源:内存溢出

    原文地址: http://outofmemory.cn/langs/674374.html

    (0)
    打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
    上一篇 2022-04-19
    下一篇 2022-04-19

    发表评论

    登录后才能评论

    评论列表(0条)

    保存