类的其他特性
1、类的成员再探
class Screen
{
public:
typedef std::string::size_type pos;
// using pos=std::string::size_type; 同上等价
Screen()=default; //因为Screen有另一个构造函数,
//所以本函数是必须的,默认方式
Screen(pos ht, pos wd, char c):height(ht), width(wd),
contents(ht*wd,c){} //contents初始化的意思是,有ht乘wd个字符c初始化一个string类型
char get() const //读取光标处的字符
{
return contents[cursor]; //隐式内联
}
inline char get(pos ht, pos wd) const; //显式内联
Screen &move(pos r, pos c); //能在之后被设为内联
private:
pos cursor=0;
pos height=0, width=0;
std::string contents;
};
//虽然我们没必要在类的里面和外面都用inline来声明,但是这样
//是合法的,不过最好只在类的外部说明inline,这样更容易理解
inline //可以在函数的定义处指定
Screen &Screen::move(pos r, pos c)
{
pos row=r*width; //计算行的位置
cursor=row+c; //在行内将光标移到到指定的列
return *this; //以左值的形式返回对象
}
char Screen::get(pos r, pos c) const //在类的内部声明成inline
{
pos row=r*width; //计算行的位置
return contents[row+c]; //返回给定列的字符
}
内联函数从源代码层看,有函数的结构,而在编译后,却不具备函数的性质。内联函数不是在调用时发生控制转移,而是在编译时将函数体嵌入在每一个调用处。编译时,类似宏替换,使用函数体替换调用处的函数名。一般在代码中用inline修饰,但是能否形成内联函数,需要看编译器对该函数定义的具体处理。
可变数据成员
使用关键字mutable,这样一个const成员函数也可以改变一个可变成员的值了
类内初始值就是把类内部的数据进行默认初始化,要么放在花括号里面,要么放在=号右边,不能使用圆括号
class Screen
{
public:
typedef std::string::size_type pos;
// using pos=std::string::size_type; 同上等价
Screen()=default; //因为Screen有另一个构造函数,
//所以本函数是必须的,默认方式
Screen(pos ht, pos wd, char c):height(ht), width(wd),
contents(ht*wd,c){} //contents初始化的意思是,有ht乘wd个字符c初始化一个string类型
char get() const //读取光标处的字符
{
return contents[cursor]; //隐式内联
}
inline char get(pos ht, pos wd) const; //显式内联
Screen &move(pos r, pos c); //能在之后被设为内联
void some_member() const;
private:
pos cursor=0;
pos height=0, width=0;
std::string contents;
mutable size_t access_ctr; //即使在一个const对象内也能被修改
};
//虽然我们没必要在类的里面和外面都用inline来声明,但是这样
//是合法的,不过最好只在类的外部说明inline,这样更容易理解
inline //可以在函数的定义处指定
Screen &Screen::move(pos r, pos c)
{
pos row=r*width; //计算行的位置
cursor=row+c; //在行内将光标移到到指定的列
return *this; //以左值的形式返回对象
}
char Screen::get(pos r, pos c) const //在类的内部声明成inline
{
pos row=r*width; //计算行的位置
return contents[row+c]; //返回给定列的字符
}
void Screen::some_member() const
{
++access_ctr; //保管一个计数值,用于记录成员函数被调用的次数
}
class Window_mgr
{
private:
//这个Window_mgr追踪的Screen
//默认情况下,一个Window_mgr包含一个标准尺寸的空白Screen
std::vector<Screen> screens{Screen(24, 80, ' ')};
};
2、全部总结
/*
* 功能:类的各种特性
* 时间:2014年5月30日08:28:55
* 作者:cutter_point
*/
#include<iostream>
#include<vector>
using namespace std;
class Screen
{
public:
typedef std::string::size_type pos;
// using pos=std::string::size_type; 同上等价
Screen()=default; //因为Screen有另一个构造函数,
//所以本函数是必须的,默认方式
Screen(pos ht, pos wd, char c):height(ht), width(wd),
contents(ht*wd,c){} //contents初始化的意思是,有ht乘wd个字符c初始化一个string类型
char get() const //读取光标处的字符
{
return contents[cursor]; //隐式内联
}
inline char get(pos ht, pos wd) const; //显式内联
Screen &move(pos r, pos c); //能在之后被设为内联
void some_member() const;
private:
pos cursor=0;
pos height=0, width=0;
std::string contents;
mutable size_t access_ctr; //即使在一个const对象内也能被修改
};
//虽然我们没必要在类的里面和外面都用inline来声明,但是这样
//是合法的,不过最好只在类的外部说明inline,这样更容易理解
inline //可以在函数的定义处指定
Screen &Screen::move(pos r, pos c)
{
pos row=r*width; //计算行的位置
cursor=row+c; //在行内将光标移到到指定的列
return *this; //以左值的形式返回对象
}
char Screen::get(pos r, pos c) const //在类的内部声明成inline
{
pos row=r*width; //计算行的位置
return contents[row+c]; //返回给定列的字符
}
void Screen::some_member() const
{
++access_ctr; //保管一个计数值,用于记录成员函数被调用的次数
}
class Window_mgr
{
private:
//这个Window_mgr追踪的Screen
//默认情况下,一个Window_mgr包含一个标准尺寸的空白Screen
std::vector<Screen> screens{Screen(24, 80, ' ')};
};
class Sales_data
{
public:
void avg_price();
};
inline
void Sales_data::avg_price()
{
}
int main()
{
}
3、大四的毕业了
我不知道我2年后会是什么样的,到时候答辩的时候能否大放异彩,能都给自己一个交代,现在大二了还在学C++基础,这些都是我们大一学过了的,有部分没学过,但是大部分学了,只是没学好而已,现在各种专业课又都来了,而且是Java的那个方面的,我不知道我会不会在大三的时候完全放弃C++转而专攻Java因为我觉得Java还是有很多我不会的地方的,而且很多地方用到的技术不是C++能替代的,至少我现在这样觉得,我用的是myeclipse写Java不知道C++该用什么,难道真的要用code::block来开发,感觉code::block编写一些简单还好,到了一个大点的项目的时候就不好办了。