C++中构造函数的手动和自动调用方式
1,对象的构造通过构造函数来完成,和类名相同且没有返回值,这个时候只有参 数一个特性,构造函数可以自定义参数,这个参数一般而言就是对类进行初始 化来使用的;带有参数的构造函数的意义在于可以使得每个对象有不同的初始 化状态(生活中每个事物必然包含自己的初始化状态,不如人的出生,面向对 象用来将生活中的事物映射的程序设计领域,所以现实世界的情况都必须可以 用面向对象的语言来描述,因此带有参数的构造函数就是非常必要的);
2,带有参数的构造函数:
1,构造函数可以根据需要定义参数;
2,一个类中可以存在多个重载的构造函数;
3,构造函数的重载遵循 C++ 重载的规则;
4,代码示例:
class Test
{
public:
Test(int v)
{
// use v to initialize member
}
};
3,对象定义和对象声明的区别:
1,对象定义:申请对象的空间并调用构造函数;
1,第一步,必须申请对象所占用的内存空间;
2,第二步,调用构造函数;
2,对象声明:告诉编译器存在这样一个对象;
1,对象在哪里定义的不知道,链接的时候回去找;
2,预处理,编译器对源代码进行检查并生成目标文件,链接器在各个目标文件中寻找目标文件存在的一些名字;
3,对象声明时,没有对象定义时的两个步骤;
3,代码示例:
Test t; // 定义对象并调用构造函数; Int main()
{
// 告诉编译器存在名为 t 的Test对象;
extern Test t; return ;
}
4,对象的声明中可以在构造函数参数中给出默认值,对象的定义中不能够在构 造函数参数中给出默认值;
4,构造函数的自动调用(第一种初始化对象方式):
#include <stdio.h> class Test
{
public:
Test()
{
printf("Test()\n");
} Test(int v)
{
printf("Test(int v), v = %d\n", v);
}
}; int main()
{
Test t; // 调用 Test()
Test t1(); // 初始胡第一种方式的参数式自动调用,调用 Test(int v);这里也是定义对象,看上去非常像函数调用,但是这里是告诉编译器要调用带有参数的函数,由重载规则确定调用的是那个构造函数;
Test t2 = ; // 初始化第一种方式的赋值式自动调用,调用 Test(int v);C 语言中初始化的方法,定义一个变量后,立即指明一个值,通过赋值符号指明;这在面向对象中其实也是对象的定义,并且指明想用右值初始化左值; t = t2; // 这是赋值操作,这里运行后不会调用构造函数,没有打印语句;初始化会调用构造函数,赋值则看后续课程; int i = ; // 用 1 对 i 进行初始化;
i = ; // 用 1 对 i 进行赋值;赋值和初始化是不同的;在面向对象当中,不同在于初始化是要调用构造函数的; int i(); // 初始化的第二种写法,同 int i = 100;; printf("i = %d\n", i); return ;
}
1,实验结果说明:
1,初始化和赋值看上去相同之处在于当初始化用赋值符号表达的时候;
2,不同之处在于初始化要调用构造函数,而赋值不会;
5,构造函数的调用:
1,一般情况下,构造函数在对象定义时被自动调用;
2,一些特殊情况下,需要手工调用构造函数:
1,如何创建对象数组;
6,构造函数的手工调用(第二种初始化对象方式)编程实验:
#include <stdio.h> class Test
{
private:
int m_value;
public:
Test()
{
printf("Test()\n"); m_value = ;
}
Test(int v)
{
printf("Test(int v), v = %d\n", v); m_value = v;
}
int getValue()
{
return m_value;
}
}; int main()
{
Test ta[]; // 按照 C 语言的方法定义 3 个 Test 对象的数组 ta;结果调用了 3 个 Test() 函数; for(int i=; i<; i++) // 循环结果打印出 3 个 0,这不一定是我们想要的;编译器默认的调用了 Test();
{
printf("ta[%d].getValue() = %d\n", i , ta[i].getValue());
} Test ta[] = {Test(), Test(), Test()}; // 手动调用构造函数; for(int i=; i<; i++) // 循环结果为 0 1 2;分别调用了相应的构造函数;
{
printf("ta[%d].getValue() = %d\n", i , ta[i].getValue());
} Test t = Test(); // 初始化第二种方式,手工调用构造函数; printf("t.getValue() = %d\n", t.getValue()); return ;
}
7,小实例:
1,需求:开发一个数组类解决原生数组的安全性问题:
1,提供函数获取数组长度;
1,C++ 要兼容 C 语言中的数组,但是 C 语言中的数组没有长度信息,用着用着就越界了;
2,提供函数获取数组元素;
3,提供函数设置数组元素;
8,数组类的实现编程实验:
1,IntArray.h 文件:
#ifndef _INTARRAY_H_
#define _INTARRAY_H_ class IntArray
{
private:
int m_length;
int* m_pointer;
public:
IntArray(int len);
int length();
bool get(int index, int& value); // 用 bool 类型作为返回值是为了安全性,安全性的体现见数组类的实现;
bool set(int index ,int value);
void free(); // 用来释放 m_pointer 指向的堆空间
}; #endif
2,IntArray.cpp 文件:
#include "IntArray.h" IntArray::IntArray(int len) // 不加作用域分辨符时,是全局函数(此时仅名字前缀相同而已),所以要加作用域分辨符指明是数组类中的函数;
{
m_pointer = new int[len]; // new int(len) 指的是设置初始值; for(int i=; i<len; i++)
{
m_pointer[i] = ;
} m_length = len;
} int IntArray::length()
{
return m_length;
} bool IntArray::get(int index, int& value)
{
bool ret = ( <= index) && (index < length()); // 进行安全性检查,是安全性的体现; if( ret )
{
value = m_pointer[index]; // 通过引用返回一个值;
} return ret; // 越界则返回 false;
} bool IntArray::set(int index, int value)
{
bool ret = ( <= index) && (index < length()); if( ret )
{
m_pointer[index] = value;
} return ret;
} void IntArray::free()
{
delete[]m_pointer;
}
3,IntArray 的使用:
#include <stdio.h>
#include "IntArray.h" int main()
{
IntArray a(); for(int i=; i<a.length(); i++)
{
a.set(i, i + );
} for(int i=; i<a.length(); i++)
{
int value = ; if( a.get(i, value) )
{
printf("a[%d] = %d\n", i, value);
}
} a.free(); return ;
}
4,这里展示了面向对象的强大,我们可以通过类来封装一些之前学习到的概念,并且可以将这些概念上的缺陷通过封装来弥补开来;
9,小结:
1,构造函数可以根据需要定义参数;
2,构造函数之间可以存在重载关系;
3,构造函数遵循 C++ 中重载函数的规则;
4,对象定义时会触发构造函数的调用;
1,构造函数调用方式分为自动调用和手工调用两种;
2,自动调用的形式又分为参数式和赋值式;
3,即初始化时,分为两种调用方式三种书写形式;
5,在一些情况下可以手动调用构造函数;
C++中构造函数的手动和自动调用方式的更多相关文章
- Hybrid App开发模式中, IOS/Android 和 JavaScript相互调用方式
IOS:Objective-C 和 JavaScript 的相互调用 iOS7以前,iOS SDK 并没有原生提供 js 调用 native 代码的 API.但是 UIWebView 的一个 dele ...
- Python中包(package)的调用方式
一.什么是Python Package 如何区分你看到的目录是一个Python Package包呢?其实很简单,你只要看这个名录下是否有“__init__.py”这个文件就好了,如果有那么就是Pyt ...
- javascript中时间的手动创建date的方式
new Date("month dd,yyyy hh:mm:ss"); new Date("month dd,yyyy"); new Date(yyyy,mth ...
- C++中构造函数详解及显式调用构造函数
C++构造函数详解及显式调用构造函数 c++类的构造函数详解 一. 构造函 ...
- C++中构造函数作用
一. 构造函数是干什么的 class Counter { public: // 类Counter的构造函数 // 特点:以类名作为函数名,无返回类型 Counter() { m_value = ; } ...
- Spring Cloud项目中通过Feign进行内部服务调用发生401\407错误无返回信息的问题
问题描述 最近在使用Spring Cloud改造现有服务的工作中,在内部服务的调用方式上选择了Feign组件,由于服务与服务之间有权限控制,发现通过Feign来进行调用时如果发生了401.407错误时 ...
- C++C++中构造函数与析构函数的调用顺序
http://blog.csdn.net/xw13106209/article/details/6899370 1.参考文献 参考1: C++继承中构造函数.析构函数调用顺序及虚函数的动态绑定 参考2 ...
- C++中构造函数和析构函数的调用顺序
一般而言,析构函数调用的顺序和构造函数调用顺序相反,但是,对象的存储类别可以改变调用析构函数的顺序.举例说明: CreateAndDestroy类的定义 CreateAndDestroy类的成员函数的 ...
- C++学习笔记(7)----类的数组中构造函数和析构函数的调用顺序
C++类的数组中构造函数和析构函数的调用顺序(2) 对于如下的代码: #include<iostream> using namespace std; class CBase { priva ...
随机推荐
- vue学习-day02(自定义指令,生命周期)
目录: 1.案例:品牌管理 2.Vue-devtools的两种安装方式 3.过滤器,自定义全局或私有过滤器 4.鼠标按键事件的修饰符 5.自定义全局指令:让文本框获取焦点 ...
- linux下为已经编译好的php环境添加mysql扩展(php安装完成后如何添加mysql扩展)
问题背景 平常我们都是先安装mysql,然后才能去安装php.假如先安装php,后安装mysql,由于php需要连接mysql,因而在php引擎中需要配置使用mysql.so扩展.这时需要手动编译生成 ...
- XML 验证
拥有正确语法的 XML 被称为“形式良好”的 XML. 通过 DTD 验证的 XML 是“合法”的 XML. 形式良好的 XML 文档 “形式良好”或“结构良好”的 XML 文档拥有正确的语法. “形 ...
- sh_05_偶数求和
sh_05_偶数求和 # 计算 0 ~ 100 之间 所有 偶数 的累计求和结果 # 开发步骤 # # 1. 编写循环 确认 要计算的数字 # 2. 添加 结果 变量,在循环内部 处理计算结果 # 1 ...
- 容器适配器————stack
只能访问 stack 顶部的元素:只有在移除 stack 顶部的元素后,才能访问下方的元素. 堆栈操作 top():返回一个栈顶元素的引用,类型为 T&.如果栈为空,返回值未定义. push( ...
- 模型层ORM操作
一.ORM操作 1.关键性字段及参数 DateField 年月日 DateTimeField 年月日时分秒 auto_now: 每次操作改数据都会自动更新时间 auto_now_add: 新增数据的时 ...
- sqli-labs(27)
0X01 先查询闭合 ?id=' 报错 ?id='' 正确 知道是’的闭合语句 0X02那么开始我们的注入之旅 空格过滤了 尝试一下%0a绕过 #也被过滤了 那么用and '1'='1构造闭合 ?i ...
- P1309 瑞士轮 (吸氧了)
P1309 瑞士轮 题解 1.这题可以模拟一下 2.sort吸氧可以过(可能是排序有点慢吧,不开会T) sort排序时注意: return 1 是满足条件,不交换 return 0是不满足,交换 代码 ...
- 提示标签title折行
使用代码换行共两种代码,均可实现html标签内title内容显示时换行.换行代码符分别为:“ ”和“ ”以上符合数字输入均必须英文半角模式输入.使用时候,在需要换行地方任选一种(组)换行符号代码即可.
- php5.6编译安装apache
1.下载源码包wget 网址/php-5.6.30.tar.gz2.解压源码包tar -zxvf php-5.6.30.tar.gz3.创建一个安装目录mkdir /usr/local/php4.进入 ...