5.3-day03-C++建構函式/this指標/解構函式
阿新 • • 發佈:2018-11-29
四、
5.建構函式
class 類名 {
...
類名 (形參表) {
建構函式體;
}
};
當一個物件被建立時,建構函式會自動被執行,其引數來自構造實參。
int i = 10;
int i (10);
6.建構函式可以通過構造引數實現過載
7.如果一個類沒有定義任何建構函式,那麼系統就會預設地為其提供一個無參建構函式,該建構函式對於基本型別的成員變數不做初始化,對於類型別的成員變數,呼叫其相應型別的無參建構函式初始化。
8.物件的建立過程
分配記憶體->呼叫建構函式
->呼叫類型別成員的建構函式->建構函式的程式碼
9.初始化表
class 類名 {
類名(...) : 初始化表 {
建構函式體;
}
};
const int x = 100;
x = 100;
int& a = b;
a = b;
1)如果類中含有常量或引用型的成員變數,必須通過初始化表對其初始化。
2)成員變數的初始化順序僅於其被宣告的順序有關,而與初始化表的順序無關。
class A {
public:
A (char* psz) : m_str (psz),
m_len (strlen (psz)) private:
size_t m_len;
string m_str;
};
練習:實現一個Clock類支援兩種工作模式,計時器和電子鐘。
00:01:00
14:05:37
#include <iomanip>
cout << setw (10) << setfill ('0') << 12;
0000000012
Clock
時、分、秒
走 - 顯示、滴答
五、this指標
1.一般而言,在類的建構函式或成員函式中,關鍵字this表示一個指標,對於建構函式而言,this指向正在被構造的物件,對於成員函式而言,this指向呼叫該函式的物件。
2.this指標的用途
1)在類的內部區分成員變數。
2)在成員函式中返回呼叫物件自身。
3)在成員函式內部通過引數向外界傳遞呼叫物件自身,以實現物件間互動。
老 -問題-> 學
師 <-答案- 生
class A {
B& m_b;
};
class B {
A& m_a;
};
sizeof (A) ?
class C {
C m_c;
};
六、常函式與常物件
1.如果在一個類的成員函式的引數表後面加上const關鍵字,那麼這個成員函式就被稱為常函式,常函式的this指標是一個常指標。在常函式內部無法修改成員變數,除非該變數具有mutable屬性。而且在常函式內部也無法呼叫非常函式。
2.常物件:擁有const屬性的物件,物件引用或指標。
常物件只能呼叫常函式。
同型的常函式和非常函式可以構成過載關係。常物件呼叫常版本,非常物件呼叫非常版本。如果沒有非常版本,非常物件也可以呼叫常版本。
const XXX 函式名 (const YYY yyy) const {
...
}
七、解構函式
class 類名 {
~類名 (void) {
解構函式體;
}
};
當一個物件被銷燬時自動執行解構函式。
區域性物件離開作用域時被銷燬,堆物件被delete時被銷燬。
如果一個類沒有定義任何解構函式,那麼系統會提供一個預設解構函式。預設解構函式對基本型別的成員變數什麼也不幹,對類型別的成員變數,呼叫相應型別的解構函式。
一般情況下,在解構函式中釋放各種動態分配的資源。
構造:基類->成員->子類
析構:子類->成員->基類
1.cpp
static_cast <目標型別>(源型別變數)
argthis.cpp
clock.cpp
constfunc.cpp
init.cpp
integer.cpp
main.cpp
retthis.cpp
s.h
s.cpp
student.cpp
this.cpp
this指標: 一般而言,在類的建構函式或成員函式中,關鍵字this表示一個指標, 對於建構函式而言,this 指向正在被構造的物件,對於成員函式而言, this指向呼叫該函式的物件。
來自為知筆記(Wiz)
1.cpp
靜態型別轉換:
#include <iostream>
using namespace std;
void foo (const int& a) {
cout << a << endl;
}
int main (void) {
char c = 'A';
foo (static_cast<int> (c));
return 0;
}
argthis.cpp
#include <iostream>
using namespace std;
class Student;
class Teacher {
public:
void educate (Student* s);
void reply (const string& answer) {
m_answer
= answer;}
private:
string m_answer;
};
class Student {
public:
void ask (const string& question, Teacher* t) {
cout << "問題:" << question << endl;
t->reply ("不知道。");
}
};
void Teacher::educate (Student* s)
{s->ask ("什麼是this指標?", this);
cout << "答案:" << m_answer << endl;
}
int main (void) {
Teacher t;
Student s;
t.educate (&s);
return 0;
}
void ask (const string& question, Teacher* t) {
cout << "問題:" << question << endl;
t->reply ("不知道。");
void Teacher::educate (Student* s) {
s->ask ("什麼是this指標?", this);
cout << "答案:" << m_answer << endl;
clock.cpp
#include <iostream>
#include <iomanip>
using namespace std;
class Clock {
public:
Clock (bool timer = true) :
m_hour (0), m_min (0), m_sec (0) {
if (! timer) {
time_t t = time (NULL);
tm* local = localtime (&t);
m_hour = local->tm_hour;
m_min = local->tm_min;
m_sec = local->tm_sec;
}
}
void run (void) {
for (;;) {
show ();
tick ();
}
}
private:
void show (void) {
cout << '\r' << setfill ('0')
<< setw (2) << m_hour << ':'
<< setw (2) << m_min << ':'
<< setw (2) << m_sec << flush;
// printf ("\r%02d:%02d:%02d", m_hour,
// m_min, m_sec);
}
void tick (void) {
sleep (1);
if (++m_sec == 60) {
m_sec = 0;
if (++m_min == 60) {
m_min = 0;
if (++m_hour == 24)
m_hour = 0;
}
}
}
int m_hour;
int m_min;
int m
};
int main (void) {
Clock clock (false);
clock.run ();
return 0;
}
<< setw (2) << m_hour << ':'
<< setw (2) << m_min << ':'
<< setw (2) << m_sec << flush;
constfunc.cpp
#include <ios
tream>using namespace std;
class A {
public:
// void bar (void) {
// cout << "非常bar" << endl;
// }
void bar (void) const {
cout << "常bar" << endl;
}
// void XXXbarYYY (A* this) {}
void foo (void) const {
// m_i = 100;
const_cast<A*>(this)->m_i = 100;
}
void print (void) const {
cout << m_i << endl;
}
// _ZNK1A3fooEv (const A* this) {
// const_cast<A*>(this)->m_i = 100;
// }
int m_i;
};
void func (void) /*const*/ {}
int main (void) {
A a;
a.foo ();
a.print ();
const A& r = a;
r.bar ();
// XXXbarYYY (&r); // const A*
a.bar ();
// XXXbarYYY (&a); // A*
return 0;
}
init.cpp
#include <iostream>
using namespace std;
int g_data = 1000;
class A {
public:
A (void) : m_c (100), m_r (g_data) {
// m_c = 100;
/// m_r = g_data;
}
void print (void) {
cout <initc << ' ' << m_r << endl;
}
private:
const int m_c;
int& m_r;
};
int main (void) {
A a;
a.print ();
return 0;
}
integer.cpp
#include <iostream>
using namespace std;
class Double {
public:
Double (double data) :
m_data (new double (data)) {
cout << "構造" << endl;
}
~Double (void) {
cout << "析構" << endl;
delete m_data;
}
void print (void) const {
cout << *m_data << endl;
}
private:
double* m_data;
string m_lable;
};
int main (void) {
// {
Double d1 (3.14);
d1.print ();
// }
Double* d2 = new Double (1.23);
delete d2;
cout << "再見!" << endl;
return 0;
}
main.cpp
#include "s.h"
// 使用Student類
int main (void) {
Student s ("張飛", 25);
s.eat ("包子");
return 0;
}
retthis.cpp
#include <iostream>
using namespace std;
class Counter {
public:
Counter (void) : m_data (0) {}
Counter& inc (void) {
++m_data;
return *this;
}
void print (void) {
cout << m_data << endl;
}
private:
int m_data;
};
int main (void) {
Counter c;
// c.inc ();
// c.inc ();
// c.inc ();
c.inc ().inc ().inc ();
c.print (); // 3
return 0;
}
s.h
#ifndef _S_H
#define _S_H
#include <string>
using namespace std;
// 宣告Student類
class Student {
public:
Student (const string& name = "", int age = 0);
void eat (const string& food);
private:
string m_name;
int m_age;
};
#endif // _S_H
s.cpp
#include <iostream>
using namespace std;
#include "s.h"
// 實現Student類
Student::Student (const string& name /* = "" */,
int age /* = 0 */) : m_name (name),
m_age (age) {}
void Student::eat (const string& food) {
cout << m_name << "," << m_age << "," << food
<< endl;
}
student.cpp
#include <iostream>
using namespace std;
class A {
public:
A (int a) {}g++ g
};
class Student {
private:
string m_name;
int m_age;
A m_a;
public:
void eat (const string& food) {
cout << m_age << "歲的" << m_name
<< "同學正在吃" << food << "。" << endl;
}
// void _ZN7Student3eatERKSs (Student* this,
// const string& food) int{
// cout << this->m_age << "歲的"<<this->m_name
// << "同學正在吃" << food << "。" << endl;
// }
void setName (const string& name) {
if (name == "2")
cout << "你才" << name << "!" << endl;
else
m_name = name;
}
void setAge (int age) {
if (age < 0)
cout << "無效的年齡!" << endl;
else
m_age = age;
}
// 建構函式
Student (const string& name, int age) :
m_a (100) {
m_name = name;
m_age = age;
}
// 無參構造
Student (void) : m_a (100) {
m_name = "沒名";
m_age = 0;
}
// 單參構造
Student (const string& name) : m_a (100),
m_name (name), m_age (0) {
m_name = "哈哈";
}
};
int main (void) {
Student s1 ("張飛", 25);
s1.eat ("包子");
// _ZN7Student3eatERKSs (&s1, "包子");
Student s2 = Student ("趙雲", 22);
s2.eat ("燒餅");
// _ZN7Student3eatERKSs (&s2, "燒餅");
Student s3;
s3.eat ("煎餅果子");
Student* s4 = new Student ("關羽", 30);
s4->eat ("烤鴨");
delete s4;
Student& s5 = *new Student ();
s5.eat ("麵條");
delete &s5;
Student sa1[3] = {s1, s2};
sa1[0].eat ("KFC");
sa1[1].eat ("KFC");
sa1[2].eat ("KFC");
Student* sa2 = new Student[3] {s1, s2}; // 2011
sa2[0].eat ("KFC");
sa2[1].eat ("KFC");
sa2[2].eat ("KFC");
delete[] sa2;
Student s6 ("劉備");
s6.eat ("米飯");
return 0;
}
this.cpp
#include <iostream>
using namespace std;
class A {
public:
A (int data) : data (data) {
cout << "構造: " << this << endl;:set cursorline
// this->data = data;
}
void foo (void) {
cout << "foo: " << this << endl;
cout << this->data << endl;
}
int data;
};
int main (void) {
A a (1000);
cout << "main: " << &a << endl;
a.foo ();
A* pa = new A (1000);
cout << "main: " << pa << endl;
pa->foo ();
delete pa;
}
this指標: 一般而言,在類的建構函式或成員函式中,關鍵字this表示一個指標, 對於建構函式而言,this 指向正在被構造的物件,對於成員函式而言, this指向呼叫該函式的物件。
來自為知筆記(Wiz)