做网站asp和asp.net有没有专门做布料的网站
做网站asp和asp.net,有没有专门做布料的网站,个人网站界面设计图片,西安公司网站设计前言
在C语言中#xff0c;当我们定义了一个结构体时#xff0c;通常需要编写一个函数来初始化它#xff0c;否则在创建结构体变量时容易忘记调用初始化函数#xff0c;导致程序出错。但在C中#xff0c;我们将不会有这样的烦恼#xff0c;前提是编写了正确的构造函数。…前言
在C语言中当我们定义了一个结构体时通常需要编写一个函数来初始化它否则在创建结构体变量时容易忘记调用初始化函数导致程序出错。但在C中我们将不会有这样的烦恼前提是编写了正确的构造函数。 构造函数 构造函数是类的特殊成员函数之一在实例化对象时由编译器自动调用且在对象整个生命周期内仅调用一次。尽管名为“构造”但构造函数的主要任务并非是开空间创建对象而是初始化对象。当对象被定义时对象的整体空间被分配但对象内的成员变量还未定义构造函数的作用就是完成对象成员变量的初始化工作。需要注意的是构造函数不能被显式调用而是在对象创建时自动执行。 接下来以日期类为例演示一下构造函数的一些书写规则
class Date
{
public:// 构造函数Date(int year, int month, int day){_year year;_month month;_day day;}// print 函数稍后用来测试打印一下数据void print() { cout _year - _month - _day endl; }private:int _year; int _month;int _day;
}; 函数名字与类名相同没有返回值也不用写 void且可以被重载。需要注意的是编译器会在每个成员函数中隐藏一个指向对象本身的指针即 this 指针以便在函数内部访问对象的成员。 来看下它的使用
int main()
{Date d1(2024, 1, 29);d1.print();return 0;
}
程序运行起来没有任何问题但是很显然现在的构造函数是有缺陷的在定义对象时必须给参数因此我们需要重载一个无参的构造 // 在Date类中的考虑到篇幅就不每次都把整个类写出来Date(){_year 1;_month 1;_day 1;}
但是这样还是有些多余我们完全可以利用缺省参数把有参无参合二为一 Date(int year 1, int month 1, int day 1){_year year;_month month;_day day;}
这样Date类的构造函数就比较完善了。 能否不写
如果我们不写构造函数会发生什么程序会崩溃吗这里先给一个结论当没有显示定义构造函数时编译器会自动生成一个无参的默认构造函数一旦用户显式定义编译器将不再生成。那么问题来了编译器生成的默认构造是什么行为呢它会怎么去初始化我们的对象先通过下面这段代码来探究一下
class Date
{
public:void print() { cout _year - _month - _day endl; }private:int _year; int _month;int _day;
};int main()
{// 注意这里不传参数时不要带括号不然成函数调用了Date d1;d1.print();return 0;
}
现在我们的Date类完全是在裸奔我们定义一个对象并调用它的print函数发现得到的全是随机值。可见编译器生成的默认构造对内置类型不处理值是不确定的。那对于自定义类型呢继续通过下面这一段代码来探究一下
class Stack
{
public:Stack(int capacity 4){cout Stack(int capacity 4) endl;}private:int* _a;int _size;int _capacity;
};class MyQueue
{
public:private:Stack _s1;Stack _s2;
};int main()
{MyQueue q;return 0;
}
这里栈的构造函数我们让它简单打印一下信息看它有没有被调用 。程序运行后我们发现打印了两次信息可见栈的构造函数被调用了两次。可见编译器生成的默认构造对于自定义类型会去调用它的默认构造。 这里提出了一个概念——默认构造稍微解释一下什么是默认构造1. 无参数的构造函数 2. 有参数但同时是全缺省的构造函数 3. 编译器生成的。这三种都能称为默认构造但是很显然这三种在一个类里只会存在一个简而言之不需要传参就能调用的都可以称为默认构造。 倘若这个栈没有默认构造把缺省值去掉那么不好意思编译器报错。这种情况怎么办呢这时候就需要初始化列表登场了。 初始化列表
构造函数通常可以分为两个部分初始化列表和函数体。在构造函数体内我们可以进行变量的赋值操作严格来说这并不是初始化而是赋初值。因为初始化只能进行一次而函数体内的赋值操作可以多次执行。因此成员变量的定义初始化是在初始化列表中进行的 你可能会好奇为什么需要初始化列表在函数体内赋值不也好好的但是有些成员变量在定义时必须初始化如引用、const 修饰的成员变量。还有就是像上面提的没有默认构造函数的自定义类型成员也可以在初始化列表中通过传参来调用构造或者不想用它的默认构造也可以在初始化列表里传参构造。 通过这段代码来看看用法 class Stack
{
public:// 语法规定这样写Stack(int capacity 4):_capacity(capacity),_size(0),_a(nullptr){cout Stack(int capacity 4) endl;}private:int* _a;int _size;int _capacity;
};class MyQueue
{
public:MyQueue(){}private:Stack _s1;Stack _s2;
};int main()
{MyQueue q;return 0;
}
对于MyQueue来说它的构造函数虽然什么都没有但是它还是会去调用自定义类型成员的默认构造因为初始化列表才是成员变量定义的地方而初始化列表中又没有给自定义类型成员显示定义。
class Stack
{
public:Stack(int capacity):_capacity(capacity),_size(0),_a(nullptr){cout Stack(int capacity) endl;}private:int* _a;int _size;int _capacity;
};class MyQueue
{
public:MyQueue():_s1(1),_s2(2){}private:Stack _s1;Stack _s2;
};int main()
{MyQueue q;return 0;
}
现在对于没有默认构造函数的自定义类型成员只需要在初始化列表中传参数就行了。 C11中新增了一个特性可以在成员变量的声明那里给缺省值这个缺省值实际上就是在构造函数的初始化列表中使用的初始值。如下所示 class MyQueue
{
public:MyQueue(){}private:Stack _s1 1;Stack _s2 2;
};
值得一提的是这里除了缺省值还涉及到隐式类型转换。 小题目
class A
{
public:A(int a):_a1(a),_a2(_a1){}void Print() { cout _a1 _a2 endl; }private:int _a2;int _a1;
};int main()
{A aa(1);aa.Print();return 0;
}
这个程序在vs下运行得到的是1和随机值因为成员变量在类中声明次序就是其在初始化列表中的初始化顺序与其在初始化列表中的先后次序无关。 补充 一般情况下我们需要自己编写构造函数。然而如果成员变量在声明时已经有了缺省值或者这些成员变量是自定义类型且具有默认构造函数则可以考虑不编写构造函数。 值得注意的是构造函数可以设为私有这样做的话外部代码将无法直接实例化对象只能通过特殊手段如定位 new 来创建对象。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/92222.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!