C++面向对象编程之——构造函数(一)

别再手动点运行了!用西门子PLC1200自动触发VisionMaster流程(S7通信保姆级教程) 本文详细介绍了如何通过西门子PLC1200与VisionMaster的S7通信协议实现工业视觉自动化触发。从硬件连接到PLC端信号处理逻辑设计,再到VisionMaster事件配置实战,提供了一套完整的保姆级教程,帮助工程师实现高效、稳定的工业视觉自动化系统。 阅读详情

之前学习C++面向对象编程,只知道构造函数是创建实例对象时被自动调用;然后陆续看了一些书,知识点比较分散,现对构造函数进行一个全面总结,以便更加深入理解构造函数。


目录

  • 构造函数是什么?

  • 构造函数形式?

  • 默认构造函数
  • 构造函数初始化列表

1.构造函数是什么?

构造函数:类中通过一个或者多个特殊的成员函数来控制其对象初始化过程。构造函数的任务是初始化类中的数据成员,无论何时只要类的对象被调用,就会执行构造函数。并且,特殊在于构造函数与类名一致,无返回值。

 

构造函数特点
1                一个或多个的成员函数
2                与类名一致,并且无返回值
3               类对象被调用,就会执行构造函数
4               任务是初始化类中的数据成员

 


2.构造函数形式?

默认的构造函数

我们在一个类中没有定义构造函数,创建了实例对象却能通过编译运行。这是为什么呢?哦,其实类通过一个特殊的构造函数来控制默认初始化过程,这个函数称之为默认构造函数,并且它无任何实参。

编译器创建的合成默认构造函数通过如下规则初始化类的数据成员:

  • 类中存在初始值,通过初始值来初始化数据成员;

  • 否则,默认初始化。

 某些类不能依赖与默认的构造函数

  • 只有当一个类中没有声明构造函数时,编译器才会自动生成默认的构造函数;
  • 对于某些类,默认的构造函数可能会执行错误的行为。当一个类中定义了内置类型或者复合类型但是没有初始化,用户在创建类对象就可能得到得到未定义的值。(编译器不会报错,但是确实会引发未定义行为)
  • 有时候编译器无法未某些类合成默认的构造函数。如:一个类中包含其他类型的成员且这个成员的类型没有默认的构造函数,在此情况下,必须自定义默认构造函数。
#ifndef SALE_DATA_H
#define SALE_DATA_H
using namespace std;
class Sale_data
{
	public:
		Sale_data() =default; //默认的构造函数 
		Sale_data(const std::string &s):bookNo(s){}
		Sale_data(const std::string &s,unsigned n,double p):
				bookNo(s),units_sold(n),revenue(p*n){}
		Sale_data(std::istream &is)
		{
			read(is,*this);
		}
				
		std::string bookNo;
		unsigned units_sold=0;
		double revenue=0.0;
	protected:
};

#endif

其中Sale_data()=default;是C++11新标准中要求编译器生成默认构造函数,可以出现在类内部或外部。当我们定义了其他的构造函数时,也必须要默认的构造函数。

一般情况下,都是在类内定义构造函数,但是我们仍能在类外部定义构造函数,只不过要分清楚在类外面的构造函数是哪一个类的成员。将上述代码中最后一个构造函数改成在类外,如下:

Sale_data(std::istream &is)
{
	read(is,*this); //read函数的作用从is中,
	//读取一条交易信息存放在this对象中。 
}

其中使用*this是将对象当成一个整体来访问,而不是直接访问对象的某个成员。

 构造函数的初始化列表

如上程序所示,构造函数参数列表之后,函数体之前的部分就是构造函数的初始化列表。它的作用是为新创建的对象一个或多个数据成员初始化(不是赋值)。对于初始化列表中初始化与赋值之间的区别,以及数据成员初始化顺序。

  • 初始化与赋值之间区别

string foo="Hello World"; //定义并初始化
string bar;  //默认初始化一个空对象
bar="Hello World"; // 为bar赋一个新值 

//对象的数据成员通过赋值形式初始化 
Sale_data::Sale_data(const std::string &s,unsigned cnt,double price)
{
		bookNo=s;
		units_sold=cnt;
		revenue=price*cnt;
}

有时候我们可以忽略初始化和赋值的区别,初始化操作时直接初始化数据成员;而赋值操作则是先初始化再赋值。其实还是存在很大的差异性,事关底层效率问题。我们都知道C++为底层而服务,最注重的就是效率问题,后者平白无故就多了一次次的赋值操作。

  • 不能忽略的构造函数初始化列表

当成员有const,引用或者属于某种类类型,但是该类没有定义默认的构造函数,我们不得不使用成员初始化列表。如:

#include<iostream>
using namespace std;
class ConstRef
{
public:
	ConstRef(int ii);
private:
	int i;
	const int ci;  //const数据成员
	int &ri;  //引用
};

ConstRef::ConstRef(int ii)
{
	i = ii;
	ci = ii;
	ri = i;
}
//ConstRef::ConstRef(int ii) :i(ii), ci(ii), ri(ii) {}
int main(void)
{
	ConstRef ref(2);
	return 0;
}

我们都知道const常量和引用必须要直接初始化,通过赋值操作将会引发错误,编译出现的错误如下:1>g:\dev\ctor\ctor error C2789: “ConstRef::ci”: 必须初始化常量限定类型的对象
C2530: “ConstRef::ri”: 必须初始化引用
C2166: 左值指定 const 对象

而使用构造函数初始化列表形式则不会出现错误,因为这种形式本来就是直接初始化。

因此,我们必须养成对构造函数数据成员列表初始化的好习惯,一是为了避免不必要的错误,而是为了C++的高效性!

  • 数据成员初始化顺序

#include<iostream>
using namespace std;
class X
{
	int i; //声明顺序i,j
	int j;
public:
	X(int val) :j(val), i(j) {} //列表初始化形式上好像是
			//用val初始化j,然后用j初始化i; 
	void print()
	{
		cout << i << "," << j << endl;
	}
};
int main(void)
{
	X x(3);
	x.print();
	return 0;
}

通过成员初始化列表在形式上看起来好像是列表初始化形式上好像是 用val初始化j,然后用j初始化i;然而类中数据成员的初始化顺序只与数据成员的声明有关,而与成员初始化列表无关,因此正确的打开方式是首先用未初始化的j(垃圾值)初始化i,再用val初始化j,程序运行的结果为:-858993460,3。

CloudSat卫星数据高效下载与自动化处理指南 本文详细介绍了CloudSat卫星数据的高效下载与自动化处理方法,包括交互式图形界面和wget批量下载技巧,以及使用Python脚本实现自动化处理和数据质量控制。内容涵盖从数据准备到实战应用的完整流程,特别适合气象研究和气候建模领域的工作者提升工作效率。 阅读详情

相关推荐

嵌入式:简单的service框架

在嵌入式中,我们获取一个资源、设置一个变量、更新数据的话最直接的方式就是直接调用一个函数。这样的写法也可以满足基本的功能,前提是这个系统是只要一个任务,只有一个while(1)如图1.1。图1.1当有两个或者两个以上的任务的时候,同时调用一个函数(设置一个状态值、操作同一个资源、操作指针等行为)的流程如图1.2。图1.2当两个任务同时操作一个资源的时候,就会有重入的问题,会导致想不到的异常问题(数据不对、指针异常等)。

stupid的博客 987

c++面向对象程序设计学习总结:类的构造函数(初始化),析构函数以及二者间的调用顺序

一、构造函数——初始化/赋值 所有构造函数的函数名与类名相同!!! 我们以表示复数的类来举例: class Complex{ public: //成员函数 private: double real,imag; } 1.默认构造函数(无参~): 默认构造函数不需要用户调用,而是在建立对象时自动执行。 Complex(){/*还可以加上一些语句,例如real=0,image=0;如果...

derbi123123的博客 1165

手把手教你用ESP32-C3打造智能聊天机器人-立创实战派

本文将详细介绍如何利用立创ESP32-C3开发板,烧录小智AI程序,快速实现一个功能强大的聊天机器人。

举世誉之而不加劝,举世非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。 5544

C++面向对象程序设计 - 构造函数

C++提供了构造函数来处理对象的初始化,构造函数是一种特殊的成员函数,与其他成员函数不同,它不需要用户来调用,而是在建立对象时自动执行。构造函数名称必须与类同名,而不能由用户任意命名,以便编译系统能识别它把它作为构造函数处理。它不具体任何类型,也不返回任何值。构造函数的功能由用户定义,可根据初始化的要求设计函数体和函数参数。而且如果用户未定义构造函数,C++系统会自动生成一个构造函数,只是这个构造函数体是空的。

觉醒法师的专栏 1458

6.4 直流无刷电机(BLDC):测试与性能评估

本文系统阐述了直流无刷电机(BLDC)的测试与性能评估方法,涵盖参数测量、性能测试、测试平台设计及可靠性评估。详细介绍了绕组电阻、电感和反电动势的测量原理与修正方法,以及转矩-转速特性、效率分析和动态响应测试的技术要点。通过搭建高精度测功机系统,结合自动化数据处理,实现对电机性能的全面评估。最后讨论了温升、振动、EMC等特殊测试方法,为BLDC电机的设计验证和质量控制提供了完整的技术路径。

技术工作者 446

微信小程序启用蓝牙设备特征值变化时的notify功能

注意:这里的serviceUUID、notifyCharacteristicUUID 我会在后面写入数据时做重点说明。isNotifyBLECharacteristic:false, //是否启用蓝牙设备服务特征 notify。二、启用蓝牙设备特征值变化时的notify功能。下一篇 将继续介绍 微信小程序蓝牙设备写入数据。

wsk198726的专栏 1173

C++面向对象基础-构造函数

存在,当成员变量出现指针类型时,默认的拷贝构造函数会导致两个对象的成员变量指向同一处,改变一处另一处也会改变不符合面向对象的设计规范,这种现象被称为”浅拷贝“。如果我们有一个默认构造函数,编译器不会创建默认构造函数,会创建拷贝构造函数。如果我们有一个有参构造函数,编译器不会创建默认构造函数,会创建拷贝构造函数。创建有参构造函数,编译器不会创建无参构造函数,会创建拷贝构造函数。创建无参构造函数,编译器不会创建无参构造函数,会创建拷贝构造函数。手动添加构造函数,编译器就不会自动添加构造函数。

m0_74937538的博客 755

基于FPGA的多级CIC滤波器实现四倍插值

基于FPGA的多级CIC滤波器实现四倍插值 原文链接:基于FPGA的多级CIC滤波器实现四倍插值 在《基于FPGA的多级CIC滤波器实现四倍抽取一》和《基于FPGA的多级CIC滤波器实现四倍抽取二》中我们先来了解滑动平均滤波器、微分器、积分器以及梳状滤波器原理以及它们的幅频响应。此篇我们将用verilog实现基于FPGA的多级CIC滤波器实现四倍插值。 1 CIC滤波器的基本概述 CIC(积分梳状...

baidu_34971492的博客 3142

C++ 面向对象基础-构造函数

构造函数,构造函数进行初始化赋值,函数默认值。 拷贝构造函数,浅拷贝与深拷贝。 析构函数。 构造函数是一种特殊的成员函数,用于创建对象时初始化。

weixin_67273669的博客 899

Sigrity Power DC Package Multi-Resistor Compact ET Model Extraction模式提取封装基板电热阻模型

DIE(定义DIE的参数):material设置为silicon(硅),Attach material(贴片的材料,设置为Die Attach),Attach thickness(贴片的材料的厚度,厚度设置为0.001mm,点击ok。Cap为覆盖材料,Material定义材料类型,thickness定义厚度,length和width定义长宽,Adhesive Material为胶的材料,Adhesive Material为胶的厚度,本例不定义,跳过即可。

weixin_54787054的博客 440

手把手入门YOLO到改进优化教程 | 【P2基础篇】数据标注+环境搭建+模型训练

本节以 YOLO自定义目标检测训练为主线,带你从零开始完成 数据标注 → 环境搭建 → 模型训练 → 结果的流程。使用labelImg制作符合YOLO格式的自定义数据集。在Windows基于 Python + Conda 创建独立虚拟环境,安装 PyTorch + CUDA + ultralytics,配置 PyCharm 运行环境。本节不仅使用自定义数据集进行演示,同时也用公开数据集训练 YOLO,查看训练日志与可视化结果(PR、P/R/F1 曲线等)等。

嵌入式阿齐Archie 2万+

C++面向对象编程入门:构造函数与析构函数(一)

出处:PConline     作者:管宁      责任编辑:xietaoming   请注意,这一节内容是c++的重点,要特别注意!   我们先说一下什么是构造函数。   上一个教程我们简单说了关于类的一些基本内容,对于类对象成员的初始化我们始终是建立成员函数然后手工调用该函数对成员进行赋值的,那么在c++中对于类来说有没有更方便的方式能够在对象创建的时候就自动初始化成员变量呢,这一点对操

Q_Jizi(七之子)的专栏 1167

Luma AI技术浅析(一)

是一款基于人工智能的3D内容生成平台,旨在通过深度学习技术实现高效、高质量的3D场景、物体和动画的生成。Luma AI 主要利用了等技术,以实现从图像、视频到3D模型的转换和生成。

m0_75253143的博客 1733

cpp反汇编分析之构造函数

子类构造函数先调用父类。子类保留父类一块空间。 以一个例子分析: class A { public: A() { } ~A() { cout<<"~A"<<endl; } }; class B:public A { public: B(A &a):_a(a) {

jinya 761

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

C++类的构造函数

详细讲解C++类中的构造函数,包含各种细节,一次讲明白!

长岛冰茶去冰的博客 1万+

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

【C++】构造函数 利用构造函数对类对象进行初始化

有关构造函数与析构函数的知识点

TPON的博客 1万+

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

深入浅出C++面向对象编程

封装将数据(成员变量)和操作数据的函数(成员函数)绑定在一起,并通过访问修饰符(public、protected、private)对外部进行数据隐藏。继承允许新类(派生类)基于已有类(基类)构建,重用、扩展或修改基类的行为。

2301_77034008的博客 8879

【C++面向对象编程】概述

C++面向对象编程通过类、对象、封装、继承和多态等特性,实现了代码的高内聚、低耦合。掌握这些技术不仅能提升开发效率,还能构建更健壮、可维护的软件系统。

byte轻骑兵的技术小窝 1576

关于C++中构造函数的讨论

关于C++中几种构造函数的讨论

mo_xiao_yang的博客 1776

【cpp】构造函数

构造函数主要分为三类:默认构造函数(无参构造函数)、有参构造函数、拷贝构造函数(包括了拷贝赋值运算符,移动构造函数,移动赋值运算符)

qq_44784242的博客 1159

如何掌握C++面向对象编程:CPP-Crash-Course终极指南

面向对象编程(OOP)是C++语言的核心特性,也是从C程序员成功转型为C++开发者的关键所在。CPP-Crash-Course项目为C程序员提供了一个完整而实用的C++速成教程,特别专注于**C++类与对象**的深度解析。本文将带你深入了解这个优秀的开源项目,掌握C++面向对象编程的核心概念和实践技巧。 ## 📚 CPP-Crash-Course项目概述 CPP-Crash-Course是一

gitblog_00023的博客 555

c++中构造函数的调用顺序

c++中构造函数的调用顺序 C++中调用构造函数按照如下顺序: 一:先调用虚拟基类的构造函数。并且按照它们的被继承的顺序进行构造。 二:调用非虚拟基类的构造函数,也是按照它们被继承的顺序构造。 三:调用类中成员对象的构造函数,按照声明顺序调用。 四:最后调用自己的构造函数。 举例: 对于如下代码: #include <iostream> using namespace std; class B1 { public: B1(int i) { cout&lt

hhyer的博客 6361

C++面向对象编程思想

指向对象的指针是指一个指针变量,它存储了一个对象的内存地址。通过这个指针,我们可以间接地访问和操作该对象。在 C++ 中,可以使用指针来引用或指向一个对象。指针变量存储了对象在内存中的地址,通过解引用指针,我们可以访问指针所指向的对象的成员变量和成员函数。// 创建一个 MyClass 对象// 创建指向 MyClass 对象的指针,将其指向 obj 的地址在这个例子中,ptr 是一个指向 MyClass 对象的指针,它存储了 obj 对象的地址。

weixin_41289611的博客 1930

C++的6种构造函数

C++的构造函数总结

weixin_45186425的博客 4488

C++构造函数

1 构造函数的定义及特征 构造函数是类的一种特殊成员函数,其主要作用是对类的成员进行初始化,保证每个类成员都有一个合适的初始值。 构造函数有以下特征: 函数名与类名一致 没有返回值 对象实例化时自动调用对应的构造函数 支持函数重载 构造函数语法:类名(){} 需要注意的是, 没有返回值和返回值为空是两码事。返回值为空指的是该函数有返回值,其中返回值为void类型。而支持重载则说明,在一个类中,可以同时存在多个构造函数。 在代码段1中,People类提供了两个构造函数,其中第一个是无参构造函数,第二个是有

乌有先生ii的博客 8279

C++——面向对象编程

上次学C++还是本科,似乎鄙人和C++也有七年之痒,她藏在大脑最深处,不知在哪儿,如今书到用时才恨少啊。

知识,既贵,又便宜。 1870
上一篇: C++关键字之——sizeof运算符
下一篇: C++面向对象编程之——构造函数(二)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值