C++学习笔记
来源:互联网 发布:知君本无邪by尼罗txt 编辑:程序博客网 时间:2024/06/14 13:28
class XXX;
只能以有限的方式使用已经被声明但没有定义的类类型,不能定义该类类型的对象。
但是可以声明指向该类类型的指针或者引用
inline成员函数
4种方式
1.直接写在类定义中
2.在类定义中,函数声明的前面加inline
3.类体外,定义函数加inline
4.声明和定义中都加inline
const类对象和成员函数(volatile类似)
const类对象只能访问const成员函数
const成员函数必须在声明和定义中都加const
const成员函数不能修改数据成员,但可以修改指针所指的对象
const类对象可以调用非const构造函数和析构函数,对象在构造完成
时刻到析构开始时刻,被认为是const
mutable(易变的)数据成员
将一个数据成员声明为mutable,const成员函数可以修改它
this指针
1.返回对象本身
Screen &Screen::clear()
{
}
2.copy对象判断
void Screen::copy(Screen &other)
{
}
静态数据成员
1.不占据对象的空间
2.在类定义之外初始化
#include "acct.h"
double Acct::_interestRate = 0.001;
......
//account.h
class Account
{
.......
private:
}
//account.cpp
const int nameSize; //必须的成员定义
const char name[nameSize] = "Savings Account";
3.静态数据成员的类型可以是其所属的类
class Bar
{
private:
};
4.静态数据成员可以作为类成员函数的缺省实参
extern int var;
class Foo {
private:
public:
};
静态成员函数
1.不能声明为const和volatile
2.出现在类体外的函数定义不能指定关键字static
3.不能访问非静态成员
使用前自增一般效率会更高些
命名空间namespace
namespace xx
{
}
namespace xx //可以递增
{
}
#include <iostream>
namespace xx {
}
using namespace xx; //using指令
namespace xx {
}
int main(int argc, char *argv[])
{
}
#include <iostream>
namespace xx {
}
using xx::foo; //using声明
namespace xx {
}
int main(int argc, char *argv[])
{
}
名字空间别名
namespace x = xx;
从标准输入读取字符
int ch;
ch = cin.get();
string line;
getline(cin, line); //读取一行
cerr输出不缓冲
clog输出带缓冲
void get_str(string &str);
get_str("haha"); //错误,字符串字面量不是string对象
void get_str(const string &str);
get_str("haha"); //OK
行为的分类
1.完全定义的行为:C++标准定义的行为,sizeof(char) = 1;
2.实现定义的行为: 编译器定义,int的大小,char是有符号数还是无符号数
3.未指定的行为:求值顺序 函数调用顺序
4.未定义的行为:数组越界
函数模板
1.当函数模板和普通函数都匹配时,优先考虑普通函数
2.函数模板可以重载,注意std中的函数模板,使用全局模板,::max(...)
3.特化函数模板:模板参数为空,函数名字后面提供显式参数
template<>
string const max<string const &>(string const &first, string const &second) {}
explicit 用于构造函数,它禁止编译器将构造函数参数用作从参数的类型到类类型的隐式转换
数据成员按照类定义中声明他们的顺序被初始化,而与初始化列表中的顺序无关
在类定义中初始化数据成员的三个条件:1.static成员;2.整形成员;3.const成员
而且要在类的实现文件中,定义:int const XXX::xx;
将copy构造函数和operator=函数声明为私有的,防止复制
class A
{
public:
private:
};
int main()
{
}
如果已经修改了容器,则之前声明的迭代器将不能再使用了!
vector<int> v(1);
v[0] = 100;
vector<int>::iterator it = v.begin();
cout << *it << endl;
v.push_back(200);
cout << *it << endl; //危险
任何含有vitual成员函数和公有析构函数的类,将析构函数声明为virtual
匿名命名空间只在文件作用域可见,类似于C的static
namespace
{
}
void foo()
{
}
写文件
<fstream> <ostream>
string filename;
cin >> filename;
ofstream outfile(filename.c_str());
//ofstream outfile("test.txt", ios::app); //追加
if(outfile)
{
}
else
{
}
读文件
ifstream infile;
infile.open("test.txt");
if(infile)
{
}
else
{
}
字符串流<sstream>
stringstream ss;
ss << "hello\n";
ss << 5*3 << ".\n";
cout << ss.str();
string str("1 2 3");
stringsteam ss(str);
int val;
for(int i=0; i!=3; ++i)
{
}
操作符重载
class A
{
private:
private:
};
inline istream & operator>>(istream &in, A &a) //输入
{
}
inline ostream & operator<<(ostream &out, A const &a) //输出
{
}
inline A operator*(A lhs, A const & rhs) //乘法
{
}
从文本中读取单词
string get_word(istream &in)
{
}
void read_file(string filename)
{