C++ Primer : 关键字static可以说是检验一个C++程序员基本功的不二法门,挑马桶这件事永远只有进行时

前提

C++ is a statically typed language, which means that types are checked at compile time. C++是一门静态语言,所以才有类型的check,所以需要考虑是否为static静态类型

单词pimer的释义

这纯属本人捏造的趣事。prime通常指一个人一生中最活跃,最黄金的阶段,且Prime often means "main."

作为程序员对main函数,再熟悉不过,所以《c++ primer》就是一本把C++从main函数出发以后的几乎所有细枝末节给你铺开

讲的明明白白的一本书,它也可能是你一生中最活跃,最黄金的时候与它常打交道的一本书了。

static

有一个局部变量,它的生存期在对函数的调用中持续,这是很有用的。 如果局部静态没有显式初始化式,则对其进行值初始化,这意味着将内置类型的局部静态初始化为零。

cpp 复制代码
size_t count_calls()
{
static size_t ctr = 0; // value will persist across calls
return ++ctr;
}
int main()
{
for (size_t i = 0; i != 10; ++i)
cout << count_calls() << endl;
return 0;
}

类有时需要与类关联的成员,而不是与类类型的单个对象关联的成员。

cpp 复制代码
class Account {
public:
	void calculate() { amount += amount * interestRate; }
	static double rate() { return interestRate; }
	static void rate(double);
private:
	std::string owner;
	double amount;
	static double interestRate;
	static double initRate();
};

The static members of a class exist outside any object.


We can access a static member directly through the scope operator:

cpp 复制代码
	double r;
	r = Account::rate(); // access a static member using the scope operator

即使静态成员不是其类的对象的一部分,也可以使用类类型的对象、引用或指针来访问静态成员:

cpp 复制代码
	Account ac1;
	Account& ac3 = ac1;
	Account* ac2 = &ac1;
	// equivalent ways to call the static member rate function
	r = ac1.rate(); // through an Account object or reference
	r = ac3.rate(); // through an Account  reference
	r = ac2->rate(); // through a pointer to an Account object

成员函数可以直接使用静态成员,不需要作用域操作符:

cpp 复制代码
class Account {
public:
	void calculate() { amount += amount * interestRate; }
private:
	double amount;
	static double interestRate;
	// remaining members as before
};

初始化静态成员变量

cpp 复制代码
// define and initialize a static class member
double Account::interestRate = initRate();

static const类型的使用

cpp 复制代码
class Account {
public:
	static double rate() { return interestRate; }
	static void rate(double);
private:
	static constexpr int period = 30;// period is a constant expression
	double daily_tbl[period];
	static double interestRate;
};

如果在类内部提供了初始化式,则成员的定义不能指定初始值:

cpp 复制代码
	// definition of a static member with no initializer
	constexpr int Account::period; // initializer provided in the class definition

静态数据成员可以具有不完整类型

非静态数据成员只能声明为指向其类对象的指针或引用:

cpp 复制代码
class Bar {
public:
	// ...
private:
	static Bar mem1; // ok: static member can have incomplete type
	Bar* mem2; // ok: pointer member can have incomplete type
	Bar mem3; // error: data members must have complete type
};

静态成员与普通成员的另一个区别是,可以将静态成员用作默认实参

cpp 复制代码
class Screen {
public:
	// bkground refers to the static member
	// declared later in the class definition
	Screen& clear(char = bkground);
private:
	static const char bkground;
};

继承树中的static成员,整个层次结构只定义了一个这样的成员。

cpp 复制代码
class Base {
public:
	static void statmem();
};
class Derived : public Base {
	void f(const Derived&);
};

静态成员服从普通的访问控制。如果成员在基类中是私有的,则派生类无法访问它。假设成员是可访问的,则可以通过基类或派生类使用静态成员:

cpp 复制代码
void Derived::f(const Derived& derived_obj)
{
	Base::statmem(); // ok: Base defines statmem
	Derived::statmem(); // ok: Derived inherits statmem
	// ok: derived objects can be used to access static from base
	derived_obj.statmem(); // accessed through a Derived object
	statmem(); // accessed through this object
}

类模板的static成员

cpp 复制代码
template <typename T> class Foo {
public:
	static std::size_t count() { return ctr; }
	// other interface members
private:
	static std::size_t ctr;
	// other implementation members
};

模板类静态实例化

cpp 复制代码
// instantiates static members Foo<string>::ctr and Foo<string>::count
Foo<string> fs;
// all three objects share the same Foo<int>::ctr and Foo<int>::count members
Foo<int> fi, fi2, fi3;

模板类静态初始化

cpp 复制代码
template <typename T>
size_t Foo<T>::ctr = 0; // define and initialize ctr

模板类静态成员的使用

cpp 复制代码
Foo<int> fi; // instantiates Foo<int> class
// and the static data member ctr
auto ct = Foo<int>::count(); // instantiates Foo<int>::count
ct = fi.count(); // uses Foo<int>::count
ct = Foo::count(); // error: which template instantiation?

嵌套类静态成员定义

cpp 复制代码
// defines an int static member of QueryResult
// which is a class nested inside TextQuery
int TextQuery::QueryResult::static_mem = 1024;

static_assert

水平不够,未来有时间来补上

static_cast

  1. 当将较大的算术类型赋值给较小的类型时,static_cast通常很有用。强制类型转换告知程序的读者和编译器,我们知道并且不关心潜在的精度损失。将较大的算术类型赋值给较小的类型时,编译器通常会生成警告。当我们执行显式强制转换时,警告消息将被关闭。
cpp 复制代码
// cast used to force floating-point division
double slope = static_cast<double>(j) / i;
  1. 对于执行编译器不会自动生成的转换,static_cast也很有用。例如,可以使用static_cast来检索存储在void*指针.
cpp 复制代码
void* p = &d; // ok: address of any nonconst object can be stored in a void*
// ok: converts void* back to the original pointer type
double *dp = static_cast<double*>(p);
  1. static_cast更深的运用,路还远,任重而道远呐

C++挑马桶基本功

  1. for循环的简单遍历,不在手写低效for循环。
cpp 复制代码
// print words of the given size or longer, each one followed by a space
for_each(wc, words.end(),
[](const string &s){cout << s << " ";});
cout << endl;
  1. 自从C++11有了智能指针,C++里一切稍微占据大量内存的数据都应该用智能指针,因为性能的缘故
cpp 复制代码
// C++万物可指针
class HugeData {
public:
	HugeData() {
	}
	void init() {
		data_ = new std::list<HugeData*>{};
	}
	void work() {
	}
private:
	static std::list<HugeData*>* data_;
};

// 但是智能指针岂不更香
class HugeData {
public:
	HugeData() {}
	void init() {
		data_ = std::make_shared<std::list<std::shared_ptr<HugeData>> >();
	}
	void work() {}
private:
	static std::shared_ptr < std::list<std::shared_ptr<HugeData>> > data_;
};
相关推荐
东风吹柳16 分钟前
观察者模式(sigslot in C++)
c++·观察者模式·信号槽·sigslot
A懿轩A25 分钟前
C/C++ 数据结构与算法【栈和队列】 栈+队列详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·栈和队列
汪洪墩26 分钟前
【Mars3d】设置backgroundImage、map.scene.skyBox、backgroundImage来回切换
开发语言·javascript·python·ecmascript·webgl·cesium
云空32 分钟前
《QT 5.14.1 搭建 opencv 环境全攻略》
开发语言·qt·opencv
Anna。。34 分钟前
Java入门2-idea 第五章:IO流(java.io包中)
java·开发语言·intellij-idea
我曾经是个程序员1 小时前
鸿蒙学习记录
开发语言·前端·javascript
爱上语文1 小时前
宠物管理系统:Dao层
java·开发语言·宠物
大胆飞猪2 小时前
C++9--前置++和后置++重载,const,日期类的实现(对前几篇知识点的应用)
c++
1 9 J2 小时前
数据结构 C/C++(实验五:图)
c语言·数据结构·c++·学习·算法
夕泠爱吃糖2 小时前
C++中如何实现序列化和反序列化?
服务器·数据库·c++