C++面向对象基础
目录
一.作用域限定符
1.名字空间
#include <iostream>
using namespace std;
int a = 2;
namespace my_space
{
int a = 3;
int b = 4;
}
using namespace my_space;
int main()
{
int a = 1;
cout << a << endl; // 就近原则 打印1
cout << ::a << endl; // ::匿名名字空间。2
cout << my_space::a << endl; // 3
cout << b << endl;
return 0;
}
2.类内声明,类外定义
#include <iostream>
using namespace std;
class Demo
{
public:
// 类内声明
Demo();
void test(string str);
};
Demo::Demo()
{
cout << "构造函数" << endl;
}
void Demo::test(string str)
{
cout << "string =" << str << endl;
}
int main()
{
Demo d;
d.test("test");
return 0;
}
二.this指针
1 概念
this指针是一个特殊的指针,指向当前类对象的首地址。
成员函数(包括构造函数与析构函数)中都有this指针,因此this指针只能在类内使用。实际上this指针指向的就是当前运行的成员函数所绑定的对象。
#include <iostream>
using namespace std;
class Test
{
public:
void test_this()
{
cout << this << endl;
}
};
int main()
{
Test t1;
cout << &t1 << endl; // 0x61fe8f
t1.test_this(); // 0x61fe8f
Test t2;
cout << &t2 << endl; // 0x61fe8e
t2.test_this(); // 0x61fe8e
Test *t3 = new Test;
cout << t3 << endl; // 0x7c27c8
t3->test_this(); // 0x7c27c8
delete t3;
return 0;
}
2.功能
2.1 类内调用成员
● 成员(变量+函数)必须由对象调用。类中成员调用都依赖于this指针。通常由编译器自动添加。
#include <iostream>
using namespace std;
class Test
{
private:
string name;
public:
Test(string n)
{
// 编译器默认添加this指针指向当前对象
this->name = n;
}
string get_name()
{
return this->name;
}
};
int main()
{
Test t1("zhangsan");
cout << t1.get_name() << endl;
Test t2("lisi");
cout << t2.get_name() << endl;
return 0;
}
2.2 区分重名的成员变量和局部变量
#include <iostream>
using namespace std;
class Test
{
private:
string name;
public:
Test(string name)//:name(name) // 构造初始化列表区分
{
// 通过this指针在函数体中区分
this->name = name;
}
string get_name()
{
return this->name;
}
};
int main()
{
Test t1("zhangsan");
cout << t1.get_name() << endl;
Test t2("lisi");
cout << t2.get_name() << endl;
return 0;
}
2.3链式调用
● 当一个成员函数的返回值是当前类型的引用时,往往表示这个函数支持链式调用。● return后面是*this
#include <iostream>
using namespace std;
class Test
{
private:
int val = 0;
public:
Test &add(int i)
{
val += i; // val = val + i;
return *this;
}
int get_val()
{
return val;
}
};
int main()
{
Test t1;
t1.add(1);
t1.add(2);
t1.add(100);
cout << t1.get_val() << endl;
Test t2;
// 链式调用
cout << t2.add(2).add(32).add(200).get_val() << endl; // 234
// cout << t2.get_val() << endl; // 2
return 0;
}
三.stastic关键字
1.静态局部变量
使用static修饰局部变量,这样的变量就是静态局部变量。
静态局部变量在第一次调用时创建,直到程序结束后销毁,同一个类所有对象共用这一份静态局部变量。
#include <iostream>
using namespace std;
class Test
{
public:
void func()
{
int a = 1;
static int b = 1; // 静态局部变量
cout << "a=" << ++a << " " << &a << endl;
cout << "b=" << ++b << " " << &b << endl;
}
};
int main()
{
Test t1;
t1.func(); // 2 2
t1.func(); // 2 3
Test t2;
t2.func(); // 2 4
return 0;
}
2 静态成员变量
使用static修饰成员变量,这样的变量就是静态成员变量。
静态成员变量需要类内声明,类外初始化。
一个类的所有对象共用一份静态成员变量,虽然静态成员变量可以使用对象调用,但是更建议使用类名直接调用。静态成员变量可以脱离对象使用,在程序开始运行时就开辟内存空间直到程序结束后销毁。
更推荐使用类名进行调用。代码的可读性更好。
#include <iostream>
using namespace std;
class Test
{
public:
int a = 1;
// static int b = 2; // 错误 ,静态成员变量需要内类声明,类外初始化
static int b;
};
int Test::b = 1; // 类外初始化
int main()
{
cout << Test::b << " " << &Test::b << endl; // 1 0x403004
Test t1;
Test t2;
cout << t1.a++ << " " << &t1.a << endl; // 1 0x61fe8c
cout << t2.a++ << " " << &t2.a << endl; // 1 0x61fe88
cout << "-----------------" << endl;
cout << t1.b++ << " " << &t1.b << endl; // 1 0x403004
cout << t2.b++ << " " << &t2.b << endl; // 2 0x403004
cout << Test::b << " " << &Test::b << endl; // 3 0x403004
return 0;
}
3 静态成员函数
使用static修饰成员函数,这样的函数就是静态成员函数。
与静态成员变量相似的有:
● 都可以通过类名直接调用,也可以通过对象调用(推荐使用类名直接调用)
● 都可以脱离对象使用。
静态成员函数没有this指针,不能在静态成员函数中调用同类中其他非静态成员,但是静态成员函数可以调用静态成员。
#include <iostream>
using namespace std;
class Test
{
public:
void func0()
{
// func1();
cout << "非静态成员函数" << endl;
}
// 静态成员函数
static void func1()
{
// func0(); // 错误,静态成员函数没有this指针
cout << "静态成员函数1" << endl;
}
static void func2()
{
// func1();
cout << "静态成员函数2" << endl;
}
};
int main()
{
// Test::func1(); // 通过类名直接调用
Test t1;
t1.func0();
// t1.func1();
t1.func2();
return 0;
}
#include <iostream>
using namespace std;
class Test
{
public:
void func0()
{
// func1();
cout << "非静态成员函数" << endl;
}
// 静态成员函数
static void func1(Test &t)
{
// t.func0();
Test t3;
t3.func0();
// func0(); // 错误,静态成员函数没有this指针
cout << "静态成员函数1" << endl;
}
static void func2()
{
// func1();
cout << "静态成员函数2" << endl;
}
};
int main()
{
// Test::func1(); // 通过类名直接调用
Test t1;
t1.func0();
t1.func1(t1);
t1.func2();
return 0;
}
4 单例设计模式(了解)
设计模式是一套被反复使用,多人知晓的,经过分类的,代码设计经验的总结。通常用于面向对象的语言,如:Java、C++、C#。
#include <iostream>
using namespace std;
// 单例设计模式
class Singleton
{
private:
Singleton(){}
Singleton(const Singleton&s){}
static Singleton *instance; // 静态成员变量指针
public:
// 静态成员函数
static Singleton* get_instance()
{
if(instance == NULL)
{
instance = new Singleton;
}
return instance;
}
static void delete_instance()
{
if(instance != NULL)
{
delete instance;
instance = NULL;
}
}
};
Singleton * Singleton::instance = NULL;
int main()
{
Singleton *s1 = Singleton::get_instance();
Singleton *s2 = Singleton::get_instance();
cout << s1 << endl;
cout << s2 << endl;
return 0;
}
四、const关键字(掌握)
1 const修饰成员函数
const修饰的成员函数,表示常成员函数。
特性如下:
● 可以调用成员变量,但是不能修改成员变量的值
● 不能调用非const修饰的成员函数,哪怕这个函数没有修改成员变量。
建议只要成员函数不修改成员变量就使用const修饰。比如:show、print等函数。
#include <iostream>
using namespace std;
class Demo
{
private:
int a;
public:
Demo(int a)
{
this->a = a;
}
void func0()
{
cout << get_demo() << endl;
cout << "哈哈哈哈哈哈" << endl;
}
int get_demo()const
{
return a;
}
void test()const
{
// a++; // 错误 const修饰的成员函数,不能修改成员变量
cout << a << endl; // 可以调用
// func0(); // 错误 const修饰的成员函数,不能调用非const修饰的成员函数
cout << get_demo() << endl;
}
};
int main()
{
Demo demo(1);
cout << demo.get_demo() << endl;
demo.func0();
demo.test();
return 0;
}
2.const修饰对象
#include <iostream>
using namespace std;
class Demo
{
private:
public:
int a;
Demo(int a)
{
this->a = a;
}
void func0()
{
// cout << get_demo() << endl;
cout << "哈哈哈哈哈哈" << endl;
}
int get_demo()const
{
return a;
}
void test()const
{
// a++; // 错误 const修饰的成员函数,不能修改成员变量
cout << a << endl; // 可以调用
// func0(); // 错误 const修饰的成员函数,不能调用非const修饰的成员函数
cout << get_demo() << endl;
}
};
int main()
{
// const Demo demo(1); // 常量对象
Demo const demo(1); // 两种初始化的方式,等效于上一行
// demo.a = 2; // 错误const修饰的对象,无法修改成员变量
cout << demo.a << endl; // 可以调用但是无法修改
// demo.func0(); // 错误const修饰的对象,无法调用非const修饰的成员函数
cout << demo.get_demo() << endl;
return 0;
}
3.const修饰成员变量
const修饰的成员变量为常成员变量,表示改成员变量的值无法被修改。
常成员变量存在两种初始化的方式:
● 直接赋值
声明之后赋值:
● 构造初始化列表
上述两种方式同时使用时,前者失效,以后者为准。
#include <iostream>
using namespace std;
class Demo
{
private:
const int a = 1; // 直接赋值
const int b = 2;
const int c = 3;
public:
// 构造初始化列表赋值
Demo(int a,int b,int c):a(a),b(b),c(c){}
void show()
{
cout << a << " " << b << " " << c << endl;
}
void test()
{
// a++; // 错误,常成员变量无法被修改
// b++;
// c++;
}
};
int main()
{
Demo d(10,20,30);
d.show();
d.test();
return 0;
}
4 const修饰局部变量
const修饰局部变量,表示该局部变量不可被修改。
这种方式常用于修饰引用参数。
#include <iostream>
using namespace std;
class Demo
{
private:
const int a = 1; // 直接赋值
const int b = 2;
const int c = 3;
public:
// 构造初始化列表赋值
Demo(int a,int b,int c):a(a),b(b),c(c){}
void show()
{
cout << a << " " << b << " " << c << endl;
}
void test(const int &f)
{
// f++; // 错误
cout << f << endl;
const int e = 1;
// e++; // 错误,const修饰的局部变量,无法被修改
}
};
int main()
{
Demo d(10,20,30);
d.show();
d.test(2);
return 0;
}
5.constexpr 常量表达式
#include <iostream>
using namespace std;
class Test
{
public:
constexpr static int a = 1; // a=1在编译期确定
// constexpr int b = 2; 错误
const int c = 3;
};
被constexpr修饰的内容表示在编译期间可以确定,C++中部分代码是需要在编译期间确定。
#include <iostream>
#include <array> // 后面要学习的一个头文件
using namespace std;
// 表示是否可以在编译期间计算出返回值
constexpr int calc_len(int i)
{
return i+5; // 随便写的计算规则
}
int main()
{
// 5表示创建的arr对象的长度,必须在编译期间确定
array<int,5> arr;
// 编译期间可以计算出结果为6,正确
array<int,calc_len(1)> arr2;
int i = 1;
// 编译期间无法计算出最后结果,报错
// array<int,calc_len(i)> arr3; 错误
return 0;
}
原文地址:https://blog.csdn.net/qq_64136247/article/details/142600098
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!