所谓声明式是告诉编译器某个东西的名称和类型,但是略去细节。
每个函数的声明式揭示其签名式,也就是参数和返回类型,一个函数的签名等同于该函数的类型。
定义式的任务是提供声明式所遗漏的一些细节,对对象而言,定义式是编译器为此对象拨发内存地点,对function或function template而言,定义式提供了代码本体,对class或class template而言,定义式列出了他们的成员。
初始化是“给予对象初值的过程”,对用户自定义类型的对象而言,初始化由构造函数执行。
default构造函数是一个可被调用而不带任何实参者,这样的函数要不没有参数,要不每个参数都有缺省值。copy构造函数被用来“以同型对象初始化自我对象”,copy assignment操作符是被用来从一个同型对象中拷贝值到自我对象,区别在于有没有个新对象被定义。
用#define可能会导致你是用的名称未进入符号表;若#define AA=6,,可能导致目标代码中出现多份6,解决此问题的办法是用const替换#define。
//define误用举例 #define MAX(a, b) a > b ? a : b int a = 5, b = 0; MAX(++a, b) //a++调用2次 MAX(++a, b+10) //a++调用一次
对const和enum的解释
#include <iostream> #include <vector> #include <unordered_map> using namespace std; class Solution { private: unordered_map<int,vector<int>> cache{{1,{1}},{2,{1,2}},{3,{2,1,3}},{4,{2,1,4,3}},{5,{3,1,2,5,4}}}; private: vector<int> beautifulArrayCore(int N) { if(cache.find(N)!=cache.end()) return cache[N]; vector<int> res; vector<int> oddRes=beautifulArrayCore((N+1)/2);//N个数中共有(N+1)/2个奇数 vector<int> evenRes=beautifulArrayCore(N/2);//N个数中共有N/2个偶数 for(auto& i:oddRes) res.push_back(2*i-1); for(auto& i:evenRes) res.push_back(2*i); cache[N]=res; return res; } public: vector<int> beautifulArray(int N) { if(N<=0) return {}; return beautifulArrayCore(N); } }; int main() { Solution s; vector<int> res(s.beautifulArray(8)); for(auto i:res) cout<<i<<‘ ‘; cout<<endl; return 0; } class GamePlayer { private: static const int num=6;//声明该常量——这是一个声明式。in class初始值设定 int arr[num];//使用该常量 }; //但是c++要求对使用的任何东西提供一个定义式,但是如果是class的专属常量又是static类型,则需特殊 //处理。只要不取他们的地址,可以声明使用他们而无需提供定义式,但是如果取某个class专属常量的地址 //或你不取其地址编译器坚持要看到定义式,则你需要提供一个定义式。 const int GamePlayer::num;//要把此式子放进实现文件而不是头文件;在声明时已经提供初始值, //现在不提供初始值 class GamePlayer { private: enum{num=6};//编译期间需要一个class常量,但是编译器不允许编译期间完成in class初值设定,用enumerate代替 int arr[num];//使用该常量 };
宏实现工厂模式
using namespace std; typedef void *(*register_fun)(); class CCFactory{ public: static void *NewInstance(string class_name){ auto it = map_.find(class_name); if(it == map_.end()){ return NULL; }else return it->second(); } static void Register(string class_name, register_fun func){ map_[class_name] = func; } private: static map<string, register_fun> map_; }; map<string, register_fun> CCFactory::map_; class Register{ public: Register(string class_name, register_fun func){ CCFactory::Register(class_name, func); } }; #define REGISTER_CLASS(class_name); const Register class_name_register(#class_name, []()->void *{return new class_name;});
const std::vector<int>::interator iter = vec.begin();//作用像T *const, ++iter 错误:iter是const std::vector<int>::const_iterator cIter = vec.begin();//作用像const T*,*cIter = 10 错误:*cIter是const
令函数返回一个常量值,往往可以降低因客户错误而造成的意外,而不至于放弃安全性和高效性。
const Rational operator* (const Rational &lhs, cosnt Rational &rhs); Rational a,b,c; if((a*b)=c) ...//在a*b的成果上调用operator=,实际上是想一个比较动作
声明为const的成员函数,不可改变non-static成员变量,在成员变量声明之前添加mutable可让其在const成员函数中可被改变。
不要在const内调用non-const成员函数,因为对象有可能被改动。
可以在non-const内调用const,因为non-const内本来就可能改动对象,可以调用const。
const_cast<char &>(static_cast<const TextBlock &>(*this))[position]; //static_cast 将TextBlock &转为const TextBlock &; //const_cast将返回值去掉const约束;
operator[]返回值类型是引用,因为
char& operator[](size_t pos) { return arr[pos]; } a[0]=‘x‘;//如果返回值是内置类型,则赋值就不合法,因为C++by value返回对象这一事实意味着改动的其实是a.arr[0]的一个副本!
原文:https://www.cnblogs.com/tianzeng/p/12296779.html