C++ 基础语法 二

C++ 基础语法 二

析构函数

一种特殊的成员函数,它会在每次删除所创建的对象时执行。析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号(~)作为前缀,它不会返回任何值,也不能带有任何参数。析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。

#include <iostream>
 
using namespace std;
 
class Line
{
    
    
   public:
      void setLength( double len );
      double getLength( void );
      Line();   // 这是构造函数声明
      ~Line();  // 这是析构函数声明
 
   private:
      double length;
};
 
// 成员函数定义,包括构造函数
Line::Line(void)
{
    
    
    cout << "Object is being created" << endl;
}
Line::~Line(void)
{
    
    
    cout << "Object is being deleted" << endl;
}
 
void Line::setLength( double len )
{
    
    
    length = len;
}
 
double Line::getLength( void )
{
    
    
    return length;
}
// 程序的主函数
int main( )
{
    
    
   Line line;
 
   // 设置长度
   line.setLength(6.0); 
   cout << "Length of line : " << line.getLength() <<endl;
 
   return 0;
}

输出

Object is being created
Length of line : 6
Object is being deleted

带多个参数构造函数

假设有一个类 C,具有多个字段 X、Y、Z 等需要进行初始化

C::C( double a, double b, double c): X(a), Y(b), Z(c)
{
    
    
  ....
}

C++拷贝构造函数

拷贝构造函数是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象。拷贝构造函数通常用于:

  • 通过使用另一个同类型的对象来初始化新创建的对象。
  • 复制对象把它作为参数传递给函数。
  • 复制对象,并从函数返回这个对象。

如果类带有指针变量,并有动态内存分配,则它必须有一个拷贝构造函数。拷贝构造函数的最常见形式如下:

classname (const classname &obj) {
    
    
   // 构造函数的主体
}
#include <iostream>
 
using namespace std;
 
class Line
{
    
    
   public:
      int getLength( void );
      Line( int len );             // 简单的构造函数
      Line( const Line &obj);      // 拷贝构造函数
      ~Line();                     // 析构函数
 
   private:
      int *ptr;
};
 
// 成员函数定义,包括构造函数
Line::Line(int len)
{
    
    
    cout << "调用构造函数" << endl;
    // 为指针分配内存
    ptr = new int;
    *ptr = len;
}
 
Line::Line(const Line &obj)
{
    
    
    cout << "调用拷贝构造函数并为指针 ptr 分配内存" << endl;
    ptr = new int;
    *ptr = *obj.ptr; // 拷贝值
}
 
Line::~Line(void)
{
    
    
    cout << "释放内存" << endl;
    delete ptr;
}
int Line::getLength( void )
{
    
    
    return *ptr;
}
 
void display(Line obj)
{
    
    
   cout << "line 大小 : " << obj.getLength() <<endl;
}
 
// 程序的主函数
int main( )
{
    
    
   Line line(10);
 
   display(line); // 这里向函数传递参数,函数复制了一份对象
 
   return 0;
}

// 输出结果
调用构造函数
调用拷贝构造函数并为指针 ptr 分配内存
line 大小 : 10
释放内存
释放内存

C++友元函数

类的友元函数是定义在类外部,但有权访问类的所有私有(private)成员和保护(protected)成员。尽管友元函数的原型有在类的定义中出现过,但是友元函数并不是成员函数。

友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类,在这种情况下,整个类及其所有成员都是友元。

如果要声明函数为一个类的友元,需要在类定义中该函数原型前使用关键字 friend,如下所示:

class Box
{
    
    
    double width;
	public:
   		double length;
   		friend void printWidth( Box box );  // 友元函数
   		void setWidth( double wid );
};

声明类 ClassTwo 的所有成员函数作为类 ClassOne 的友元,需要在类 ClassOne 的定义中放置如下声明:

扫描二维码关注公众号,回复: 17479808 查看本文章
friend class ClassTwo;
#include <iostream>
 
using namespace std;
 
class Box
{
    
    
   double width;
public:
   friend void printWidth( Box box );
   void setWidth( double wid );
};
 
// 成员函数定义
void Box::setWidth( double wid )
{
    
    
    width = wid;
}
 
// 请注意:printWidth() 不是任何类的成员函数
void printWidth( Box box )
{
    
    
   /* 因为 printWidth() 是 Box 的友元,它可以直接访问该类的任何成员 */
   cout << "Width of box : " << box.width <<endl;
}
 
// 程序的主函数
int main( )
{
    
    
   Box box;
 
   // 使用成员函数设置宽度
   box.setWidth(10.0);
   
   // 使用友元函数输出宽度
   printWidth( box );
 
   return 0;
}

this指针

在 C++ 中,每一个对象都能通过 this 指针来访问自己的地址。this 指针是所有成员函数的隐含参数。因此,在成员函数内部,它可以用来指向调用对象。友元函数没有 this 指针,因为友元不是类的成员。只有成员函数才有 this 指针。

#include <iostream>
 
using namespace std;
 
class Box
{
    
    
   public:
      // 构造函数定义
      Box(double l=2.0, double b=2.0, double h=2.0)
      {
    
    
         cout <<"Constructor called." << endl;
         length = l;
         breadth = b;
         height = h;
      }
      double Volume()
      {
    
    
         return length * breadth * height;
      }
      int compare(Box box)
      {
    
    
         return this->Volume() > box.Volume();
      }
   private:
      double length;     // Length of a box
      double breadth;    // Breadth of a box
      double height;     // Height of a box
};
 
int main(void)
{
    
    
   Box Box1(3.3, 1.2, 1.5);    // Declare box1
   Box Box2(8.5, 6.0, 2.0);    // Declare box2
 
   if(Box1.compare(Box2))
   {
    
    
      cout << "Box2 is smaller than Box1" <<endl;
   }
   else
   {
    
    
      cout << "Box2 is equal to or larger than Box1" <<endl;
   }
   return 0;
}

对象的创建

#include <iostream>
using namespace std;
 
class A{
    
    
private:
	int i;
public:
	A(){
    
     cout<<"调用没有参数的构造函数"<<endl; }
	A(int a):i(a){
    
     cout<<"调用有一个参数的构造函数"<<endl; }
	~A(){
    
    cout<<"成员变量为:"<<i<<"\t调用析构函数"<<endl;}
};
 
int main(){
    
    
	A a0;			//形式一:直接声明一个对象
	A a1(1);		//形式二:隐式调用A带一个参数的构造函数
	A a2 = A(2);		//形式三:显式调用A带一个参数构造函数
	A *p = new A(3);	//形式四:动态分配
	return 0;
}

C++对象创建与释放_破船不会沉的博客-CSDN博客

  • 析构的顺序与构造顺序相反,上面代码中构造顺序是a0,a1,a2 ;析构顺序是a2,a1,a0.
  • 在栈中创建的对象无需手动释放,系统自动回收。在堆中创建的对象需要手动释放。在运行结果中调用了4次构造函数,然而析构函数只执行了3次,没有释放指针p所指向的对象。在上面程序末尾加入代码delete p;p=NULL;
  • 需要注意的是delete p;只是释放了内存空间,指针p仍然指向那块空间,所以一定要将p指针置为NULL;

C++是多继承

派生类可以访问基类中所有的非私有成员。因此基类成员如果不想被派生类的成员函数访问,则应在基类中声明为 private。

一个基类派生了所有办法,但除下列的除外:

  • 基类的构造函数、析构函数和拷贝构造函数。
  • 基类的重载运算符。
  • 基类的友元函数。

猜你喜欢

转载自blog.csdn.net/weixin_45882303/article/details/143441371