-
C++第四天
今天讲的内容有静态成员变量和静态成员函数、引用、继承、拷贝构造函数,最后还带着我们完成了一个超市管理系统的练习。使用简书做笔记一直有个问题没解决,没有办法搜索,凭记忆是记不住哪些内容是哪天讲的,要想看之前的笔记必须挨个点开看一下才能确认,所以从今天开始打算在开头先写上当天讲的内容,便于后期查看。
对成员进行封装时对外使用public,对内使用private。
必须在初始化列表中初始化的4类:const,引用,基类,子对象。
静态变量和全局变量的区别:
静态变量是封装的,全局变量不是
全局变量谁都可以访问
static:静态成员变量
#include <iostream>
#include <string>
using namespace std;
class Good
{
public:
Good(string name, float price, int num)
{
m_strName = name;
m_fPrice = price;
m_iNum = num;
}
void info()
{
cout << "name:" << m_strName << " price:" << m_fPrice << " num:" << m_iNum << endl;
}
bool setNum(int num)
{
if (num > m_iNum)
{
return false;
}
m_iNum -= num;
return true;
}
private:
string m_strName;
float m_fPrice;
int m_iNum;
};
class Sale
{
public:
Sale(string name="sale", int num = 0)
{
m_strName = name;
m_iNum = num;
}
Good &getGood()
{
return m_good;
}
bool saleGood()
{
cout << "input num:";
int num;
cin >> num;
if (m_good.setNum(num))
{
m_iNum += num;
cout << "成功卖出商品" << num << "瓶\n";
m_good.info();
}
else
{
cout << "库存不足,销售失败" << endl;
}
}
private:
string m_strName;
int m_iNum;
public:
static Good m_good;
};
//静态成员变量是所有类对象所共享,不独立属于某个对象,必须在类外进行初始化
Good Sale::m_good("kele", 3, 890);
int main(void)
{
cout << sizeof(Sale) << endl;
cout << sizeof(Good) << endl;
//静态的成员变量先于任何对象之前就已经存在
//若静态的成员变量是public则可以通过类名直接使用
Sale::m_good.info();
#if 0
Sale sale;
sale.saleGood();
Sale sale2;
sale2.saleGood();
#endif
return 0;
}
static静态成员函数:
#include <iostream>
#include <string>
using namespace std;
class Good
{
public:
Good(string name, float price, int num)
{
m_strName = name;
m_fPrice = price;
m_iNum = num;
}
void info()
{
cout << "name:" << m_strName << " price:" << m_fPrice << " num:" << m_iNum << endl;
}
//可以通过类名直接使用
//在函数中不能访问普通的成员变量及普通的成员函数
//静态成员函数没有隐藏的this指针
//可以访问静态成员变量及静态成员函数
//使用场景:当不需要使用普通的成员变量及普通的成员函数,但是又和该类功能相关,并且可以不需要通过对象就可以访问则可以定义为静态成员函数
static Good &getInstance()
{
static Good good("kele", 3, 890);
return good;
}
bool setNum(int num)
{
if (num > m_iNum)
{
return false;
}
m_iNum -= num;
return true;
}
static void fun()
{
//cout << m_strName <<endl;// X
cout << m_test << endl;
Good good("aa", 8, 90);
good.info(); // V
//info(); // X
}
private:
string m_strName;
float m_fPrice;
int m_iNum;
static int m_test;
};
int Good::m_test = 90000;
void fun()
{
Good::getInstance().setNum(32);
Good::getInstance().info();
}
void test()
{
Good::getInstance().info();
}
int main(void)
{
#if 0
Good::getInstance().info();
fun();
test();
Good::getInstance().setNum(56);
Good::getInstance().info();
#endif
Good::fun();
return 0;
}
拷贝构造函数:
#include <iostream>
#include <string.h>
using namespace std;
class MyString
{
public:
~MyString()
{
if (NULL != m_data)
{
cout << m_data << ':';
delete []m_data;
}
cout << "~MyString()\n";
}
//只对成员变量中的值依次拷贝到新的成员变量中去叫浅拷贝
//除了拷贝变量中的值,连空间里的值也要拷贝过来叫深拷贝
//拷贝构造函数
MyString(const MyString &other)
{
m_iLen = other.m_iLen;
if (NULL == other.m_data)
{
m_data = NULL;
}
else
{
m_data = new char[m_iLen+1];
if (NULL != m_data)
{
strcpy(m_data, other.m_data);
}
}
cout << "MyString(MyString&)\n";
}
MyString(const char *data = NULL)
{
if (NULL == data)
{
m_data = NULL;
m_iLen = 0;
}
else
{
int len = strlen(data);
m_data = new char[len+1];
if (NULL == m_data)
{
cout << "new failed\n";
return;
}
strcpy(m_data, data);
m_iLen = len;
cout << m_data << ':';
}
cout << "MyString(...)\n";
}
const char *data()
{
return m_data;
}
private:
int m_iLen;
char *m_data;
};
void fun()
{
MyString s1("Hello");
MyString s2(s1); //调用拷贝构造函数
//MyString s2=s1; //调用拷贝构造函数
}
void test(MyString s)
{}
//void test2(int a){}
MyString &test3()
{
static MyString s("$$$$$");
return s;
}
MyString test4()
{
MyString s("$$$$$");
cout << (void*)&s << endl;
return s;
}
int main(void)
{
// fun();
// MyString ss("Hello");
// test(ss);
/// test2(90);
MyString tmp = test4();
cout << (void*)&tmp << endl;
return 0;
}
this函数:
#include <iostream>
#include <string>
using namespace std;
class Good
{
public:
Good(string name, float price, int num)
{
m_strName = name;
m_fPrice = price;
m_iNum = num;
}
//普通的成员函数形参列表中含有一个隐藏的指针
//该指针的类型为该类(Good *this)指针名字为this
void info() //相当于void info(Good *this)
{
cout << "name:" << m_strName << " price:" << m_fPrice << " num:" << m_iNum << endl;
//相当于cout << "name:" << this->m_strName << " price:" << this->m_fPrice << " num:" << this->m_iNum << endl;
}
static Good &getInstance()
{
static Good good("kele", 3, 890);
return good;
}
bool setNum(int num)
{
if (num > m_iNum)
{
return false;
}
m_iNum -= num;
return true;
}
private:
string m_strName;
float m_fPrice;
int m_iNum;
};
int main(void)
{
cout << sizeof(Good) << endl;
Good s1("kele", 2.5, 890);
Good s2("xuebi", 1.8, 900);
s1.info(); //info(&s1);
s2.info(); //info(&s2);
return 0;
}
const函数:
#include <iostream>
using namespace std;
class People
{
public:
//构造函数具体工作:
//1,给成员变量申请空间
//2,如果初始化列表中有初始化数据则使用初始化数据对成员初始化
//3,执行函数体
People(string id, string name, string born, string addr)
: m_strId(id), m_strBorn(born), m_strName(name), m_strAddress(addr)
{
//int a(90);
//m_strId = id; // X
//m_strName = name;
//m_strBorn = born; // X
//m_strAddress = addr;
}
//const成员函数
//如果不想在一个函数中对成员变量做任何修改,但是又担心被意外修改则可将此函数定义为const成员函数
void info() const //相当于void info(const People *this)
{
//m_strName = "sasas";
//cout << "id:" << this->m_strId
cout << "id:" << m_strId << " name:" << m_strName << " born:" << m_strBorn << " addr:" << m_strAddress << endl;
}
//void test(People *this)
void test()
{
cout << "test()" << endl;
}
private:
//const成员变量必须在初始化列表中初始化
const string m_strId;
string m_strName;
const string m_strBorn;
string m_strAddress;
};
int main(void)
{
const People p("1728e13291e1", "zhangsan", "1989-8-9", "shanghai");
p.info();
//p.test(); // X
//test(&p);const People *
return 0;
}
子对象的初始化必须在初始化列表中若没有显式的对子对象进行初始化则默认调用子对象的无参构造函数初始化
继承:
#include <iostream>
#include <string>
using namespace std;
class People
{
public:
People(){cout << "People()\n";}
People(string id, string name, string born, string addr)
: m_strId(id), m_strBorn(born)
{
m_strName = name;
m_strAddr = addr;
cout << "People(...)\n";
}
private:
const string m_strId;
string m_strName;
const string m_strBorn;
string m_strAddr;
};
class Student: public People
{
public:
//继承过来的基类数据的初始化必须在派生类中的初始化列表中调用基类的构造函数来初始化若没有调用,则默认调用基类的无参构造函数来初始化
Student(){cout << "Student()\n";}
Student(string id, string name, string born, string addr, string stuid, float score)
: People(id, name, born, addr)
{
m_strStuId = stuid;
m_fScore = score;
cout << "Student(...)\n";
}
private:
string m_strStuId;
float m_fScore;
};
class Teacher: public People
{
private:
string m_strLevel;
float m_fSalary;
};
int main(void)
{
//Student s;
Student s2("101011", "zhangsan", "1900-10-10", "shanghai", "stu-001", 89);
#if 0
cout << "people size:" << sizeof(People) << endl;
cout << "student size:" << sizeof(Student) << endl;
cout << "teacher size:" << sizeof(Teacher) << endl;
#endif
return 0;
}
网友评论