1.类定义和成员访问控制
main.cpp
#include <iostream>
#include "Header.h"
using namespace std;
class MyClass1
{
private:
int mCode = 100;
public:
string name = "Bill";
int value = mCode;
};
int main(int argc, const char * argv[]) {
// 类的定义
/*
类:对现实事物的抽象。汽车 : 轮子个数(属性)、载重量(属性)、搭载人数(属性)、最大的时速(属性)....
类的实例化:将抽象具体化。 汽车种类:轿车:轮子个数:4个 载重量:1000kg、搭载人数:5 最大的时速:120km/h
private 只有在内部可以访问
public 外部内部均可访问
protected
*/
MyClass1 c1; // 类的定义,c1的类型就是MyClass1
cout << "c1.name = " << c1.name << endl; // Bill
cout << "c1.value = " << c1.value << endl; // 100
MyClass1 *p_c1 = new MyClass1(); // 用指针方式访问类成员
cout << "p_c1->name = " << p_c1->name << endl; // Bill
cout << "p_c1->value = " << p_c1->value << endl; // 100
delete p_c1;
MyClass2 c2; // MyClass2在Header.h里面
cout << "c2.name = " << c2.name << endl; // Mike
cout << "c2.value = " << c2.value << endl;// 300
return 0;
}
Header.h
#ifndef class_definition_Header_h
#define class_definition_Header_h
#include <iostream>
using namespace std;
class MyClass2
{
private:
int mCode = 300;
public:
string name = "Mike";
int value = mCode;
};
#endif
2.定义和实现类中的方法
main.cpp
#include <iostream>
#include "person.h"
using namespace std;
int main(int argc, const char * argv[])
{
// 实现类中的方法
Person *p_Person = new Person();
p_Person->setCode(20);
p_Person->setName("Bill Gates");
cout << "code = " << p_Person->getCode() << endl; // 20
cout << "name = " << p_Person->getName() << endl; // Bill Gates
delete p_Person;
return 0;
}
person.cpp
#include "person.h"
//定义类中的方法
void Person::setCode(int code) // 类中的方法,setCode方法属于Person,并不是全局的函数
{
mCode = code;
}
void Person::setName(string name)
{
mName = name;
}
void Person::setValue(string value)
{
this->value = value; // 类的方法的参数名和类的成员变量名相同时,用this指向类的成员变量名
}
int Person::getCode()
{
return mCode;
}
string Person::getName()
{
return mName;
}
person.h
#ifndef __implement_method__person__
#define __implement_method__person__
#include <iostream>
using namespace std;
class Person
{
private:
int mCode;
string mName;
string value;
public:
void setCode(int code); // 声明原型时可以不指定code,如 void setCode(int)
void setName(string name); // 类中的方法
void setValue(string value);
int getCode();
string getName();
};
#endif /* defined(__implement_method__person__) */
3.内联方法
#include <iostream>
using namespace std;
class MyClass
{
public:
// 内联方法,直接在类的定义中实现方法
void method()
{
cout << "method" << endl;
}
void process();
};
/*void MyClass::method() // 这样写方法的话,在main中调用时,是地址的切换
{
}*/
inline void MyClass::process() // 在类的外部实现内联方法
{
cout << "process" << endl;
}
int main(int argc, const char * argv[]) {
// 内联方法
MyClass myClass;
myClass.method(); // 调用内联方法,相当于将代码 cout << "method" << endl; 插入到此处
myClass.process(); // 同上 cout << "process" << endl;
return 0;
}
4.类的初始化和构造方法
#include <iostream>
using namespace std;
struct MyStruct
{
int code;
string name;
};
class MyClass
{
public:
int code;
string name;
MyClass(); // 构造方法,和类名相同
MyClass(int code, string name);
MyClass(int code);
MyClass(string name);
};
MyClass::MyClass() // 一旦用户自己定义了类的构造方法,C++编译器就不会为类自动创建构造方法,就不能逐个成员的传参,即 MyClass myClass = {30, "John"}; 会报错
{
cout << "MyClass" << endl;
}
MyClass::MyClass(int code, string name)
{
this->code = code;
this->name = name;
}
MyClass::MyClass(int code)
{
this->code = code;
this->name = "null";
cout << "MyClass(int code)" << endl;
}
MyClass::MyClass(string name)
{
this->code = 1;
this->name = name;
cout << "MyClass::MyClass(string name)" << endl;
}
int main(int argc, const char * argv[])
{
// 类的初始化和构造方法
MyStruct myStruct = {20, "Mike"}; // 按顺序传参
cout << "MyStruct.code = " << myStruct.code << endl; // 20
cout << "MyStruct.name = " << myStruct.name << endl; // Mike
// 类的默认域:private,要在外部使用类成员,需要在类中指定public 结构体的默认域:public
MyClass myClass = {30, "John"};
cout << "MyClass.code = " << myClass.code << endl; // 30
cout << "MyClass.name = " << myClass.name << endl; // John
MyClass myClass1; // 打印:MyClass 。用自定义构造方法声明一个变量时,会自动调用该构造方法
MyClass myClass2 = {40}; // 打印 MyClass(int code)
MyClass myClass3 = {"Mike"}; // 打印 MyClass::MyClass(string name)
return 0;
}
5.默认构造方法和参数默认值
#include <iostream>
using namespace std;
class MyClass
{
public:
void method()
{
cout << "method" << endl;
}
MyClass(int code = 1, string name = "Bill") // 给每个参数默认值,这样在调用构造方法时,即使不传参数,也不会报错
{
}
// 按照下式这样写会产生歧义,即在调用没有参数的方法时,系统不知道该使用下式还是使用上式,定义时产生歧义并不会出错,只有在调用时才会出错,即这样写如果不调用无参数的构造方法时编译会通过
/* MyClass()
{
}*/
};
int main(int argc, const char * argv[]) {
// 默认构造方法和参数默认值
MyClass myClass1;
MyClass myClass2 = MyClass(20);
MyClass *p_class = new MyClass(10, "Mike");
return 0;
}
6.析构方法
#include <iostream>
using namespace std;
class Person
{
public:
string getName()
{
return "Bill";
}
};
class MyClass
{
private:
Person *p_Person;
int mCode;
public:
MyClass(int code)
{
p_Person = new Person();
mCode = code;
cout << "MyClass构造方法被调用 code = " << code << endl;
}
~MyClass() // 析构方法定义,无参数
{
delete p_Person;
cout << "MyClass析构方法被调用 code = " << mCode << endl;
}
};
int main(int argc, const char * argv[]) {
MyClass myClass(1); //创建在栈上,系统会自动调用析构方法 打印:MyClass构造方法被调用 code = 1 MyClass析构方法被调用 code = 1
MyClass *p_c = new MyClass(2); //new创建的空间在堆上 系统bu会自动调用析构方法 打印 MyClass构造方法被调用 code = 2
delete p_c; // 打印 MyClass析构方法被调用 code = 2
return 0;
}
7.C++11初始化对象的方式总结
#include <iostream>
using namespace std;
class MyClass
{
public:
int code;
string name;
MyClass()
{
}
MyClass(int code, string name)
{
}
MyClass(string value1, string value2)
{
}
};
int main(int argc, const char * argv[]) {
// C++11初始化对象的方式
MyClass myClass1 = {20, "Bill"};
MyClass myClass2{20, "Bill"}; // 在C++11中可以把等号去掉
MyClass myClass3 = {"abc", "bbb"};
MyClass myClass4 {"abc","bca"};
return 0;
}
8.常量(const)方法
#include <iostream>
using namespace std;
class MyClass
{
private:
int mCode = 100;
public:
int process(int code) const; // const加在后面
void method() const
{
// mCode = 200; // method用const修饰后,这句话会报错
}
};
int MyClass::process(int code) const // 常量方法要求其内部调用的函数method()也是常量
{
// mCode = code;
method();
return mCode;
}
int main(int argc, const char * argv[]) {
// const方法
// const应该放到方法参数的后面
MyClass myClass;
cout << myClass.process(200) << endl; // 100
return 0;
}
9.this指针
#include <iostream>
using namespace std;
class MyClass
{
private:
int code;
void process(){}
public:
void method(int code)
{
this->code = code;
(*this).code = code; // 效果同上
this->process();
(*this).process(); // 效果同上
}
MyClass *getObject() // 这是一个函数,函数名是getObject,返回值是指针,指向MyClass类型的值,即可以理解为:MyClass* getObject()
{
return this; // 返回this指针,指向MyClass类型的值
}
};
int main(int argc, const char * argv[])
{
// this指针
MyClass myClass;
if(myClass.getObject() == &myClass)
{
cout << "equal" << endl; // equal
}
return 0;
}
10.对象数组
#include <iostream>
using namespace std;
class MyClass
{
private:
int mCode;
public:
MyClass()
{
mCode = -1;
}
MyClass(int code)
{
mCode = code;
}
void process()
{
cout << mCode << endl;
}
};
int main(int argc, const char * argv[]) {
// 对象数组
MyClass classes[3] = {MyClass(1), MyClass(2)}; // 会自动调用没有参数的构造方法,此时如果类中只定义了有参数的构造方法,那么此句报错
classes[2].process(); // 打印 -1
MyClass classes1[] = {MyClass(1), MyClass(2)};
MyClass *pClasses = new MyClass[3];
pClasses[1].process(); // 打印 -1 ,因为并没有对数组元素进行单独初始化
MyClass *arrayMyClass[3] = {new MyClass(1), new MyClass(2)}; // 数组的每个元素是指向MyClass的指针
cout << arrayMyClass[2] << endl; // 打印0x0,没有进行初始化,空指针,此时即便没有定义无参数构造方法,也不会报错
MyClass **ppClasses;
typedef MyClass* NewType;
ppClasses = new NewType[3];
for(int i = 0; i<3;i++)
{
ppClasses[i] = new MyClass(i + 1);
}
ppClasses[2] -> process(); // 打印 3
return 0;
}
11.类中的常量
#include <iostream>
using namespace std;
class Calendar
{
private:
const int months = 12; // 这里虽然给了months赋值12,但这只有占位的作用,定义数组时,用months作为数组长度的话,会报错,即便months不用const修饰,也会报错。那怎么不报错呢?有两种方法
// 方法1,定义枚举类型
enum{months1 = 12}; // months1和12互为别名
// 方法2 静态常量,存储在全局作用域中,而不是存储在类中
static const int months2 = 12;
// float values[months]; // error,months的值会影响数组尺寸进而影响类所占内存空间时,months必须是一个常量,const定义的是类中的常量,存储在类中,static定义的存储在全局
float values1[months1]; // 编译时将months1替换为12,此时定义数组不报错
float values2[months2];
public:
void method()
{
cout << months << endl;
}
};
int main(int argc, const char * argv[]) {
// 类中的常量
Calendar calendar;
calendar.method(); // 打印 12
return 0;
}
12.类中的枚举类型
#include <iostream>
using namespace std;
class MyClass
{
private:
// 在多个枚举类型中,定义相同的枚举值时,会产生冲突,因为枚举值都是全局的,解决这个冲突的办法就是类美剧
enum egg{large = 10, medium = 20, small = 30}; // 全局枚举
enum class shirt:short{large, medium, small}; // 类枚举,short指的是枚举值以short数据类型存储, class可以用struct代替
public:
void method()
{
egg e = large;
cout << e << endl;
shirt s = shirt::medium; // 使用::,限定medium为shirt中的枚举值
cout << (int)s << endl;
}
};
int main(int argc, const char * argv[]) {
// C++中的枚举类型
MyClass myClass;
myClass.method(); // 打印 10 1
return 0;
}
|