当前位置: 首页 > news >正文

做网站需要什么资金延吉网站建设

做网站需要什么资金,延吉网站建设,网络文化经营许可证变更,阿迪达斯网站建设定位希望文章能对你有所帮助,有不足的地方请在评论区留言指正,一起交流学习! 目录 1.构造函数 1.1.构造函数体赋值 1.2 初始化列表 1.3 explicit关键字 2.Static成员 2.1.概念 2.2.静态成员函数 2.3.总结 3. 友元 3.1.友元函数 3.2.友元类 4. 内部类 5.匿名…

希望文章能对你有所帮助,有不足的地方请在评论区留言指正,一起交流学习!

目录

1.构造函数

1.1.构造函数体赋值

1.2 初始化列表

1.3 explicit关键字

2.Static成员

2.1.概念

2.2.静态成员函数

2.3.总结

3. 友元

3.1.友元函数

3.2.友元类

4. 内部类

5.匿名对象


1.构造函数

1.1.构造函数体赋值

        如下,在对象实例化的过程中,成员变量的创建时机是在进入构造函数之前;构造函数体中的代码是在成员变量已经创建后执行的,所以属于赋初值,不是初始化。
// 构造函数Date(int year,int month,int day){_year = year;_month = month;_day = day;}

        上述代码中的成员变量都是整型在创建的时候可以不用赋予初始值。 

1.2 初始化列表

       C++规定通过初始化列表(而非构造函数体),才能真正实现成员变量的初始化。初始化列表在成员变量创建时直接赋值,且仅执行一次。所以初始化列表就是成员变量定义的地方。

        其构成为以一个冒号开始,以逗号分隔的数据成员列表,每成员变量后面跟一个放在括号中的初始值或表达式。如下:

//初始化列表Date(int year, int month, int day):_year(year), _month(month), _day(day){  }

需要注意的是:

  1. 每个成员变量在初始化列表中最多只能出现一次(初始化只能初始化一次)
  2. 类中包含以下成员,必须放在初始化列表位置进行初始化:引用成员变量 ,const成员变量,自定义类型成员(且该类没有默认构造函数时)。
  3. 尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化。 也就说,不管写不写初始化列表,在对象创建的时候,都会经过初始化列表。
  4. 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关。
  5. 函数体和初始化列表都是构造函数的一部分,初始化列表的存在可以分担一些初始化的操作,但是在一些情况下不能独立完成初始化操作。

注意1 说明:

        初始化的核心含义是:为变量分配内存空间,并赋予其初始值的过程。这个过程具有 一次性的特性,一旦变量完成初始化,其内存空间就已确定,后续对它的操作只能是 “赋值”(修改已有内存中的值),而不是 “再次初始化”(重新分配内存)。

        总之:初始化就是:内存分配 + 赋初值

class Stack 
{
public:Stack(int capacity = 10):_a((int*)malloc(sizeof(int)*capacity)), _size(0), _capacity(capacity){}private:int* _a;size_t _size;size_t _capacity;};
class MyQueue
{
public:MyQueue(){}MyQueue(int capacity):_pushst(capacity),_popst(capacity){}
private:Stack _pushst;Stack _popst;
};int main()
{MyQueue mq1;MyQueue mq2(100);return 0;
}

        上述程序的结果说明,在具有默认构造函数的自定义类型,可以不用在初始化列表中写出。

注意2 说明:

        引用成员变量 ,const成员变量其必须在定义的时候初始化;因此必须采用初始化列表的方式初始化;对于有默认构造函数的自定义成员变量,初始化可以不传参数,但是没有的情况下,必须传递参数是自定义类型成员初始化。

class A
{
public:A(int a = 4):_a(a){}
private:int _a;
};class B 
{
public:B(int& ref, int a):_ref(ref), _a(a), _x(1){}private:A _aobj;int& _ref;const int _a;int _x;
};

        上述代码中含有内置类型和自定义类型,int _x=1;其中的1是缺省值,但是其可以在初始化的时候使用,虽然没有调用A类的初始化,但是程序会自动调用其初始化列表。测试程序:

int main()
{int n = 3;B bb1(n, 2);return 0;
}

运行结果

注意4 说明

class Stack
{
public:Stack(int capacity = 10): _size(0), _capacity(capacity),_a((int*)malloc(sizeof(int)* _capacity)){if (_a == nullptr){perror("malloc fail");return;}}
private:int* _a;size_t _size;size_t _capacity;};int main()
{Stack st1;return 0;
}

        上述代码将_a的定义放到最后,其采用的初始化内存空间的值,是_capacity;在初始化列表中,按照是声明的顺序来初始化的,因此,在初始化_a的时候,_capacity仍然是一个随机值,开辟的空间大小也是一个随机值。

class Test
{
public:Test(int a):_a1(a), _a2(_a1){}void Print() {cout << _a1 << " " << _a2 << endl;}
private:int _a2;int _a1;
};
int main() {Test aa(1);aa.Print();
}

上述的输出:

        证明初始化是有顺序的,先初始化的a1再初始化的a2。

1.3 explicit关键字

        构造函数不仅可以构造与初始化对象,对于接收单个参数的构造函数,还具有类型转换的作用。接收单个参数的构造函数具体表现:
1. 构造函数只有一个参数
2. 构造函数有多个参数,除第一个参数没有默认值外,其余参数都有默认值
3. 全缺省构造函数
总结:在创建新的对象的时候,仅仅传递一个参数就可以完成对象的初始化。

引入:

class D
{
public:D(int a):_a(a){ cout << "Init" << endl;}D(const D& d) {cout << "Copy" << endl;_a = d._a;}private:int _a;
};
int main()
{D dd1(5);D dd2 = 7;//隐式类型转换 7以D类构造函数创建新的临时对象,然后根据临时对象拷贝构造生成dd2//但是编译器会优化为 dd2以7直接优化的。//反例//D& dd3 = 9;const D& dd3 = 9;   //证明会产生临时变量 会调用一次 构造函数 D dd4(dd3);         //内置类型转换int a = 10;double d = a;//隐式类型转换 a转换为中间变量 double的类型然后再赋值给d}

        在上述代码中,为了提高效率,连续的调用构造,编译器一般都会优化,将连续的构造整合为一个。

        根据反汇编,可以看出,仅仅调用了一次构造,但是其特性不能忘记,中间变量具有常性,为了方式隐式类型转换,

可以在构造函数中加上explicit ,不让其构造支持隐式转换。

class D
{
public:explicit D(int a):_a(a){ cout << "Init" << endl;}D(const D& d) {cout << "Copy" << endl;_a = d._a;}private:int _a;
};

2.Static成员

引入:计算程序中有多少的对象。

int _count = 0;
class B
{
public:B(){_count++;}B(const B& b) {_count++;}~B(){_count--;}
private:};B& Func(B bb) // 进入调用拷贝构造一次创建新的对象  // 4
{B bb4;   // 5cout << __LINE__ << ": " << _count << endl; // 5return bb4; // 销毁 bb bb4    3
}
B bb1;   // 1int main()
{cout << __LINE__ << ": "<<_count << endl;B bb2;  // 2static B bb3; // 3cout << __LINE__ << ": " << _count << endl;B bb5 = Func(bb3);    //4cout << __LINE__ << ": " << _count << endl;return 0;
}

        由于全局变量的修改在程序的任何地方都可以修改,因此在C++中将全局变量封装在类中,只供一个类的使用,给静态变量增加一个约束。

2.1.概念

        声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用static修饰成员函数,称之为静态成员函数静态成员变量一定要在类外进行初始化。

class B
{
public:B(){_count++;}B(const B& b){_count++;}~B(){_count--;}
private:// 普通成员变量int _b1 = 1;int _b2 = 2;// 静态成员变量static int _count;
};
// 静态成员变量支持类外定义
int B::_count = 0;

        静态成员变量属于类本身,并非类的某个对象,所以它需要在类外进行单独定义,从而为其分配内存空间。

定义位置不受访问限定符的限制

       无论静态成员变量在类中被声明为privateprotected还是public,其定义都能在全局作用域内完成。这是因为:

  •  声明时的访问限定符,是针对访问行为的限制,而非定义行为
  •  定义静态成员变量属于类的实现细节,只要在编译时能访问到类的完整定义,就可以进行定义。

2.2.静态成员函数

class B
{
public:B(){_count++;}B(const B& b){_count++;}~B(){_count--;}// 静态成员函数没有传递 this指针,指定类域或者修改访问限定符就可以访问static int GetCount(){return _count;}
private:// 普通成员变量int _b1 = 1;int _b2 = 2;// 静态成员变量static int _count;
};
// 静态成员变量支持类外定义
int B::_count = 0;int main()
{B bb1;cout << B::GetCount() << endl;return 0;
}

        私有的成员变量访问的时候可以通过GetCount函数,但是一般的成员函数访问需要又对象,传递this指针,为了方便调用,static函数诞生了,这种函数是没有外部对象的条件下调用成员函数。静态变量和静态成员函数一般会成对存在。

引例:

// 设计一个类,在类外面只能在栈上创建对象
// 设计一个类,在类外面只能在堆上创建对象
class C
{
public:static C GetStackObj(){C cc;return cc;}//在成功分配内存后,new会返回一个指向所分配类型对象的指针。static C* GetHeapObj(){return new C;}// 上述两个函数是在类内创建的对象,想要在类外不用对下个直接调用,就加上static
private :int _a1 = 1;int _a2 = 2;};int main()
{C::GetHeapObj;C::GetStackObj;return 0;
}

2.3.总结

静态成员变量:

        静态成员所有类对象所共享,不属于某个具体的对象,存放在静态区;所以在创建的类的时候静态成员就已经初始化了;因此不要将其和普通的成员变量混淆,静态成员变量输出类的本身,其他的成员变量是蓝图。所以其定义的时候要在类外定义,不参加对象的初始化。当然静态成员函数也是受访问限定符限制的。

静态成员函数:

        静态成员函数没有this指针,不能访问任何非静态成员,包括函数非静态成员的函数以及普通的成员函数。如下:随便创建的空函数,也是不可以访问或者复用的。,

3. 友元

3.1.友元函数

        友元函数可以直接访问类的私有成员,它是定义在类外部普通函数,不属于任何类,但需要在类的内部声明,声明时需要加friend关键字。

特点

  • 非成员函数:友元函数不属于类,定义时不需要加类作用域前缀(如 MyClass::)。
  • 访问权限:可以直接访问类的私有和保护成员,但必须通过对象实例之后才可以访问(如 obj.privateVar)。
  • 声明位置:友元声明可以放在类的任意位置(public、protected 或 private),效果相同。

举例:运算符号 <<  >> 的重载

class Date
{
public:Date(int year = 2025, int month = 7, int day = 26): _year(year), _month(month), _day(day){}ostream& operator<<(ostream& _cout){_cout << _year << "-" << _month << "-" << _day << endl;return _cout;}
private:int _year;int _month;int _day;
};
int main()
{Date d1;d1 << cout;// d1 << cout; -> d1.operator<<(&d1, cout); 不符合常规调用// 因为成员函数第一个参数一定是隐藏的this,所以d1必须放在<<的左侧return 0;
}

        上述代码中的<< 的第一个操作数是d1也就是this指针;第二个操作数cout,相反了。为了转过来,只能写到类的外部,但是还要访问函数内部私有的成员变量;所以有了 friend关键字。

class Date
{
public:Date(int year = 2025, int month = 7, int day = 26): _year(year), _month(month), _day(day){}friend	ostream& operator<<(ostream& out, Date& d);private:int _year;int _month;int _day;
};
ostream& operator<<(ostream& out,Date& d)
{out << d._year << "-" << d._month << "-" << d._day << endl;return out;
}
int main()
{Date d1;cout << d1;return 0;
}

        上述代码中,对流输出的运算符重载函数写在类的外面。

friend	ostream& operator<<(ostream& out, Date& d);

        让重载函数突破访问限制;类外函数可以访问类内私有成员

友元函数不推荐多用,除去友元函数 Get Set函数,因为友元增加了耦合;让关联度更加紧密,修改类中成员不好修改。

流输入

istream& operator>>(istream& cin, Date& d)
{cin >> d._year;// 空格代表这一次输入命令的结束cin >> d._month;cin >> d._day;return cin;
}

3.2.友元类

        友元类是一种允许一个类访问另一个类私有(private)和保护(protected)成员的机制。通过友元类,被授权的类可以突破封装限制,直接操作另一个类的内部数据。        

        特性

  • 单向性:如果 A 声明 B 为友元类,B 可以访问 A 的私有成员,但 A 不能访问 B 的私有成员,除非 B 也显式声明 A 为友元。
  • 非继承性:友元关系不能被继承。即使 B 是 A 的友元,B 的派生类也不会自动成为 A 的友元。
  • 非传递性:如果 A 是 B 的友元,B 是 C 的友元,C 不会自动成为 A 的友元
class Time
{friend class Date; // 声明日期类为时间类的友元类,则在日期类中就直接访问Time类中的私有成员变量
public:Time(int hour = 0, int minute = 0, int second = 0): _hour(hour), _minute(minute), _second(second){}private:int _hour;int _minute;int _second;
};
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1): _year(year), _month(month), _day(day){}void SetTimeOfDate(int hour, int minute, int second){// 直接访问时间类私有的成员变量_t._hour = hour;_t._minute = minute;_t._second = second;}private:int _year;int _month;int _day;Time _t;
};

4. 内部类

        内部类(嵌套类) 是定义在另一个类内部的类。

特性

  1. 内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任何优越的访问权限。
  2. 内部类就是外部类的友元类;
  3. 内部类可以在外部类的public、protected、private任何部分。
  4. 内部类可以直接访问外部类中的static成员,不需要外部类的对象/类名。
  5. sizeof(外部类)=外部类,和内部类没有任何关系。内部类独立存在:外部类和内部类的对象在内存中是分离的,彼此不包含对方。
例子:
 
class A
{
private:static int k;int h;
public:class B // B天生就是A的友元{public:void Func(const A& a){cout << k << endl;//OKcout << a.h << endl;//OK}};
};
int A::k = 1;
int main()
{A::B b;b.Func(A());return 0;
}

5.匿名对象

       匿名对象(Temporary Object) 是一种未被命名的临时对象,它在表达式中创建后立即使用,通常在当前语句结束后销毁。是一种的临时值传递方式,常用于简化代码或作为函数参数。

实例:匿名在同一行创建,在同一行销毁。

class C
{public:C(int c = 1) :_c(c){cout << "Init" << endl;}//拷贝构造函数C(C& cc){_c = cc._c;}void Func() const{cout << _c << endl;}~C(){_c = 0;cout << "Destroy" << endl;}private:int _c;};
int main()
{// 普通对象C cc1(10);cc1.Func();//匿名对象C(20); C(20).Func();//匿名对象具有常性 const C& rc = C(30);rc.Func();return 0;
}

总结

1.匿名对象可以调用一次成员函数,普通对象可以调用多次;

2.匿名对象在不被使用的赋值的情况下,用完即销毁;

3.在被赋值的情况下,匿名对象会和被赋值的对象的生命周期一样;

匿名对象的使用

void push_back(const string& s)
{cout << "push_back:" << s << endl;
}int main()
{//传递命名对象(左值)string str("11111");push_back(str);//传递匿名对象(右值)push_back(string("222222"));//传递字面量(隐式类型转换)push_back("222222");return 0;}
 push_back(str):传递命名对象(左值)
  • 过程str 是一个命名对象(左值),通过常量左值引用const string&)传递给 push_back
  • 特点
    • 不创建临时对象,直接绑定引用到 str
    • 避免拷贝,高效且安全(const 确保不修改原对象)。
 //传递匿名对象(右值)push_back(string("222222"));
  • 过程
    1. string("222222") 创建一个匿名 string 对象(右值)。
    2. 该匿名对象通过常量左值引用绑定到 push_back 的参数 s
  • 特点
    • 匿名对象在语句结束后销毁(但因被 const 引用绑定,生命周期延长至函数调用结束)。
    • 仅需一次构造(string 的构造函数),无拷贝。
push_back("222222"):传递字面量(隐式类型转换)
  • 过程
    1. "222222" 是 const char* 类型的字符串字面量。
    2. 隐式转换push_back 期望 const string&,编译器自动调用 string 的构造函数 string(const char*) 创建一个临时 string 对象。
    3. 临时对象通过常量左值引用绑定到 s
  • 特点
    • 隐式创建临时 string 对象,可能导致性能开销(构造 + 析构)。
    • 若 push_back 声明为 push_back(string s)(值传递),会额外触发一次拷贝构造。

http://www.dtcms.com/a/480708.html

相关文章:

  • 长沙网页设计广州seo代理商
  • 西安网站建设的网站网站与网页设计
  • 微信企业网站源码下载wordpress积分购买
  • 济南网站万词优化漫画 网站 源码
  • 苏州公司网站设计做自己的网站
  • 会计上网站建设做什么费用机床网站建设
  • 自己做手机版网站制作龙岗网络营销网站制作哪里好
  • 网站过期了网站建设是干什么的
  • 网站手机端制作软件用腾讯云服务器做网站
  • 手机访问不了自己做的网站制作静态网站需要什么
  • 建网站怎么挣钱的个人网站域名名字
  • 餐饮公司 网站建设怎么制作图片二维码
  • 遵义网站建设公司有哪些如何做好外贸网站建设
  • 苏州做网站哪家专业淮南网络建站公司
  • 网站优化推广方案建立什么网站可以赚钱
  • 做网站的标签及属性wordpress 方法
  • 淘宝客网站开发教程常见软件开发模型
  • 固安做网站的不支持下载的视频怎么保存下来
  • java类库
  • 专业外贸网站制作价格网站推广的渠道有
  • 网站建设及管理制度中国十大电商培训机构
  • 旅游网站建设报价单东营两学一做网站
  • 铁岭网络推广网站建设桂林网站优化注意事项
  • 惠城中山网站建设wordpress头像显示空白
  • 企业官网建站费用本地门户网怎么做
  • 做素材网站赚钱吗高端网站建设 上海
  • 怎么组建企业网站wordpress 连载
  • 建设商城购物网站wordpress自定义分页
  • 最专业的微网站开发微信如何建商城网站
  • 网站图片自动轮换怎么做的做任务挣钱的网站聚