首页 > 编程语言 >C++:类、类的构造与析构

C++:类、类的构造与析构

时间:2022-10-11 22:34:32浏览次数:56  
标签:函数 与析构 构造 C++ 析构 double 构造函数 Stock

概念引述

  C++的OOP特点已经耳熟能详,封装,继承,多态。封装主要体现在namespace、stock、funtion;继承体现为类继承;多态体现为类之间通过继承关联时。因此C++进阶的前提就是熟知类的使用,明白类是创建数据和操作数据的一种重要方法。

类的访问权限

引自https://www.runoob.com/cplusplus/cpp-inheritance.html

类的定义与实现

//头文件
class Stock
{
private:
	std::string cpy_name;//股票名
	long shares;//股票的股数
	double val_share;//单只股票的价格
	double tol_value;//股票的总价值
	void set_total()//只在类的内部可见,声明+定义
	{
		Stock::tol_value = Stock::shares * Stock::val_share;
	}
public:
	Stock(const std::string& co, long n, double price);//构造函数
	~Stock();//析构函数
	void buy(long n, double price);
	void sell(long n, double price);
	void update(double price);
	void show();
};
#include <iostream>
#include "stock00.h"

//构造函数
Stock::Stock(const std::string& co, long n, double price)
{
	Stock::cpy_name = co;
	if (n < 0)
	{
		std::cout << "number of shares is negative!" << std::endl;
		Stock::shares = 0;
	}
	else
	{
		Stock::shares = n;//股票的股数
		Stock::val_share = price;//每股的价格
		Stock::set_total();//总价格
	}
}

//析构函数
Stock::~Stock()
{
	std::cout << "调用析构函数:" << cpy_name << std::endl;
}

void Stock::buy(long n, double price)
{
	if (n < 0)
	{
		std::cout << "number of shares is negative! transaction is fail!" << std::endl;
		Stock::shares = 0;
	}
	else
	{
		Stock::shares += n;
		Stock::val_share = price;//每股的价格
		Stock::set_total();//总价格
	}
}

void Stock::sell(long n, double price)
{
	if (n < 0)
	{
		std::cout << "number of shares is negative! transaction is fail!" << std::endl;
		Stock::shares = 0;
	}
	else if (n > shares)
	{
		std::cout << "number of shares is over! transaction is fail!" << std::endl;
	}
	else
	{
		Stock::shares -= n;
		Stock::val_share = price;//每股的价格
		Stock::set_total();//总价格
	}

}
void Stock::update(double price)
{
	Stock::val_share = price;//每股的价格
	Stock::set_total();//总价格
}

void Stock::show()
{
	std::cout << "Company: " << Stock::cpy_name << std::endl;
}

  类中一般包含私有和共有两部分,私有对象不允许外部访问,只能通过共有的函数去间接访问。除此之外对于那些出于隐藏的目的不宜设为公有,但又确实需要在派生类的成员函数中经常访问的基类成员,将它们设置为protected保护成员,既能起到隐藏的目的,又避免了派生类成员函数要访问它们时只能间接访问所带来的麻烦。需要说明的是:

  • 当声明时进行类成员函数声明时,此时类成员函数将被inline说明
  • 类定义于栈中,因此是先入后出的关系,这一点在调用析构函数时可以显示观察到
  • 类对象可以互相拷贝
  • 类的保护对象可以如同共有部分一样在派生类与基类中进行访问

类的构造

  类的构造我们一般称之类的构造函数,类的构造函数通常用来定义类并给类对象赋值。从“类定义的定义与实现”代码可以看到,类的构造函数形式为:

Stock(const std::string& co, long n, double price);//构造函数,类的构造函数必须与类名一致

  创建类时:

Stock ob_cat= Stock("zw",10,12);//构造函数的显示调用
Stock ob_cat("zw",10,12);//构造函数的隐式调用

  另外,C++提供了默认构造函数,如果我们没有定义构造函数,在创建类时C++编译器会自行创建一个类的默认构造函数。类的默认构造函数创建有以下三种方式

//第一种:不创建构造,C++自行创建一个默认构造函数
//stock::stock() {}

//第二种:传递默认参数创建默认构造函数
Stock(const std::string& co = "zw" , long n = 1, double price = 10);

//第三种:默认构造函数的函数重载
Stock();

  仍然需要注意,传递默认参数时,默认参数必须处于形参列表的最后。在C++11中,也提供了构造函数的新用法{}:

stock ob_cat = { "fff", 1.2, 5.5 };//C++11的新用法

类的析构

  类的析构类似于new然后delete,自动执行类的清理工作,所以一般只是定义出来或者干脆不定义,而在析构函数中不做任何操作,如果没有定义析构函数,C++编译器将执行与默认构造函数相同的操作---自行定义一个默认的析构函数。

Stock::~Stock()
{
	std::cout << "调用析构函数:" << cpy_name << std::endl;
}

  所以析构函数的执行通常在程序生命周期的末节,比如当我们新建一个int main(void)函数运行上述定义的代码时,可以显式观察到构造函数的执行顺序,这里大家只需关注构造函数的执行步骤即可:

  这里能观察到当我们在第一步重新调用一个构造函数进行类对象的赋值时,析构函数被调用。这是因为当调用构造函数进行类对象的二次复制时,本质是新建了一个临时类对象,并将其值赋值给原先的类对象,随后将仙剑的临时类对象删除,此时会调用析构函数。除此之外,如果我们再构造函数进行new,对应的在析构函数也需要delete!

Const与类对象

  现在我们知道,类本质就是数据的创建与操作,那如果我们想创建一个不被修改的类对象时,只是打印其中内容应该怎末办呢?C++仍然规定了类成员的cosnt限定规则,拿上面定义的show()函数来说:

void show() const;

  如果不这样做,编译器无法保证const 类对象进行打印时不被修改!

标签:函数,与析构,构造,C++,析构,double,构造函数,Stock
From: https://www.cnblogs.com/YiMo9929/p/16782894.html

相关文章

  • C++ 栈和典型迷宫问题
    1.前言栈是一种受限的数据结构,要求在存储数据时遵循先进后出(LastInFirstOut)的原则。可以把栈看成只有一个口子的桶子,进和出都是走的这个口子(也称为栈顶),封闭的另一端称......
  • c++高级 面试补充
    多线程:多线程分为三个知识点:1.线程的建立,在main中要进行函数终止,  在函数中使用后才能使得main函数在线程结束后才结束。如果不使用,那么可能线程结束前,main函数就结......
  • 用VSCode和CMake编写调试C/C++
    VSCode配置编译任务与调试对象在配置的时候会用到一些vscode的变量,用${}包裹起来的那些。${workspaceFolder}是当前工作空间(或vscode所打开根文件夹)在操作系统中绝对路......
  • day 13 -类与构造器
    ##类```1/*2修饰符返回值类型方法名(...){3//方法体4return返回值;5}6*/ ```类的定义静态方法:```1//静态方法static234//非静态方法......
  • VS2019 使用 C/C++ 动态链接库 并 进行调用
     vs2019生成dll并调用的实现示例:​​https://www.jb51.net/article/179759.htm​​ 1.VS 中生成动态链接库的三种方式(导出函数) 开发环境:VS2019 创建动态链接库项目新......
  • [持续更新]C++从入门到精通
    C++编译器下载https://wwc.lanzoul.com/iRLXO0dnayde密码:33kg1.C++关键字关键词有哪些?在C++98/03关键词总计63个,分别是下面这些:asmdoifreturntypedefautodo......
  • C++ AFX_MANAGE_STATE(AfxGetStaticModuleState())的作用
    从AFX_MANAGE_STATE(AfxGetStaticModuleState())说起 AFX_MANAGE_STATE(AfxGetStaticModuleState())的作用:用于模块切换时的状态保护,1.AfxGetStaticModuleState()指向当前......
  • C++继承模型漫谈
    1、创建子类对象时,会优先创建父类部分,再创建子类部分,也就是子类对象是包含了两部分内容,(父类部分+子类部分)(图1)classTypeA{public:inta=10;voidv(){......
  • <三>从编译器角度理解C++代码的编译和链接原理
    代码点击查看代码**sum.cpp**intgdata=10;intsum(inta,intb){returna+b;}**main.cpp**externintgdata;intsum(int,int);intdata=20;intmain(......
  • 抽象类与接口的比较?构造方法,构造方法重载,什么是复制构造方法?求N的阶乘?Java环境搭建:J
    大家可分享关于Java微服务相关知识,包括但不限于Java微服务开发经验、架构组成、技术交流、中间件等内容,我们鼓励springcloud架构为基础发散出击,从而达到技术积累的目的,快来......