C++ 中的一些小问题, 持续补充
2012-03-28 01:07
351 查看
C++ Primer Plus 205
因为在 buildstr 函数中的 pstr 是局部函数 ,所以当函数结束时 pstr 被释放, 在main函数中, ps仍然指向 buildstr中的返回值 ,但是当使用完ps後 需要釋放ps,尽管之前没有在main函数中new过。
2.#include <iostream>
输出结果为16 虚函数为动态绑定的,但是当有默认参数时,编译器为了省去动态绑定默认值的低效而采用了静态绑定 即 采用基类的默认参数。
3.一个函数指针的例子
C++ Primer Plus 218
用括号括起来 *pf 是函数 pf是指向函数的指针。
内联函数比常规函数少块, 但是占据更多的代码空间,因为内联函数可以省去函数跳转到其他函数这个操作步骤,但是取而代之的是复制函数的拷贝到每个需要使用这个函数的函数的地址附近。(编译过程中扩展代码)
所以需要考虑 跳转和执行代码的比率,来判断使用内联函数获得的时间上的收益。
4.引用
int rats
int &rodents = rats
则 rodents 为rats的别名 他们指向同一个内存地址。
在初始化rodents的时候就必须绑定他的值 并且以后不再能改变绑定的对象
int & rodents = rats
等价于
int * const rodents = &rats;
当引用作为返回值时将直接返回返回值 而不是再把返回值拷贝到零时变量中。
值得注意的是,当返回值为函数中的局部变量时,外部调用的函数仍能成功访问.
或许是VS编译器的问题,这样的情况应当是被避免的。
当返回值为引用时,最好的办法是返回一个作为参数传递给函数的引用。
另外一个办法是 你可以在函数中new一个新的对象出来。但是就和第一例讲到的一样,你必须记得在外部delete他们。
b. Pointers to const objects cannot be deallocated with the
delete operator. (delete operator in MSDN).
c. Q1: const int* pInt = new int(0); //指向常量的指针
delete pInt; //error,看上一条b.
5.
template 模板递归实现。自底向上。 。。
6
输出结果为 245
1中 当 a 赋值给 b时候 b由于新分配内存空间 调用一次拷贝构造函数 c 的初始化调用一次 当c再赋值给b 是 调用的应该是 运算符 = 的重载
2中 参数传递拷贝一次, 返回值传递一次
3中 返回值调用一次
7
输出结果1413
数组X中保存的是对象的地址 在调用数组中的类型的时候会根据RTTI动态找到对象的函数
但是VECTOR容器中保存的是 父类对象A的元素 因为VECTOR是连续的内存地址, 他会把子类自动转成基类以便能封装进VECTOR中
8.
输出结果为2531 先调用b的析构函数 然后再释放B的成员变量再调用父类的析构函数
虚函数表在类地址的最开始。
operator int () const重载类转换运算符号
比如
C c;
int a = (int)c;
9
输出结果为 5 3
运行到1时 调用构造函数不是拷贝构造函数
运行到2时 创建一个临时对象调用拷贝构造函数然后释放临时对象
3时容量不够 创建新的内存空间 复制旧的到新的 释放旧的
10. static const,virtual
如果使用 是成员函数 如果使用 static 描述的 话,则不能同时为const 或者 virtual 因为,const 和 virtual内部包含了一个隐含的this指针。
未完待续..
char *buildstr(char c,int n) { char* pstr = new char[n + 1] pstr = '\n'; while(n-- > 0) pstr = c; return pstr; } int main { int times; char ch; char *ps = buildstr(ch,times); delete [] ps; }
因为在 buildstr 函数中的 pstr 是局部函数 ,所以当函数结束时 pstr 被释放, 在main函数中, ps仍然指向 buildstr中的返回值 ,但是当使用完ps後 需要釋放ps,尽管之前没有在main函数中new过。
2.#include <iostream>
class B { public: virtual int shift(int n = 2) const { return n << 2; } }; class D : public B { public: int shift(int n = 3) const { return n << 3; } }; int main() { const D d; const B *b = &d; std::cout << b->shift() << std::endl; return 0; }
输出结果为16 虚函数为动态绑定的,但是当有默认参数时,编译器为了省去动态绑定默认值的低效而采用了静态绑定 即 采用基类的默认参数。
3.一个函数指针的例子
C++ Primer Plus 218
double betsy(int) double pam(int) //声明时可以省略 参数名 double betsy(int lns) { return 0.05 * lns; } double pam(int lns) { return 0.03 * lns + 0.0004 * lns * lns; } void estimate(int lines , double(*pf)(int)) { cout << lines << "lines will take" cout << (*pf)(lines) << " hours\n"; } void main() { estimate(code , betsy); estimate(code , pam); }
用括号括起来 *pf 是函数 pf是指向函数的指针。
内联函数比常规函数少块, 但是占据更多的代码空间,因为内联函数可以省去函数跳转到其他函数这个操作步骤,但是取而代之的是复制函数的拷贝到每个需要使用这个函数的函数的地址附近。(编译过程中扩展代码)
所以需要考虑 跳转和执行代码的比率,来判断使用内联函数获得的时间上的收益。
4.引用
int rats
int &rodents = rats
则 rodents 为rats的别名 他们指向同一个内存地址。
在初始化rodents的时候就必须绑定他的值 并且以后不再能改变绑定的对象
int & rodents = rats
等价于
int * const rodents = &rats;
inline const syosp & use (syosp & sysopref) { sysopref.used++; syosp test = sysopref; //return sysopref; return test; } int main() { syosp looper = { "test", "testtest", 0 }; syosp ref; ref = use(looper); cout << ref.name << ref.quote << ref.used << endl; getchar(); }
当引用作为返回值时将直接返回返回值 而不是再把返回值拷贝到零时变量中。
值得注意的是,当返回值为函数中的局部变量时,外部调用的函数仍能成功访问.
或许是VS编译器的问题,这样的情况应当是被避免的。
当返回值为引用时,最好的办法是返回一个作为参数传递给函数的引用。
另外一个办法是 你可以在函数中new一个新的对象出来。但是就和第一例讲到的一样,你必须记得在外部delete他们。
b. Pointers to const objects cannot be deallocated with the
delete operator. (delete operator in MSDN).
c. Q1: const int* pInt = new int(0); //指向常量的指针
delete pInt; //error,看上一条b.
5.
#include <iostream> template<unsigned N> class A { public: A() { std::cout << N; } private: A<N - 1> m_a; }; template<> class A<0> { public: A() { std::cout << 'A'; } }; int main() { { A<4>(); } std::cout << std::endl; return 0; }
template 模板递归实现。自底向上。 。。
6
.#include <iostream> class A { public: explicit A(int n = 0) : m_n(n) { } A(const A& a) : m_n(a.m_n) { ++m_copy_ctor_calls; } public: static int m_copy_ctor_calls; private: int m_n; }; int A::m_copy_ctor_calls = 0; A f(const A& a) { return a; } A g(const A a) { return a; } int main() { A a; A b = a, c(a); // 1 std::cout << A::m_copy_ctor_calls; b = g(c); //2 std::cout << A::m_copy_ctor_calls; const A& d = f(c); // 3 std::cout << A::m_copy_ctor_calls << std::endl; getchar(); return 0; }
输出结果为 245
1中 当 a 赋值给 b时候 b由于新分配内存空间 调用一次拷贝构造函数 c 的初始化调用一次 当c再赋值给b 是 调用的应该是 运算符 = 的重载
2中 参数传递拷贝一次, 返回值传递一次
3中 返回值调用一次
7
.#include <iostream> #include <vector> class A { public: A(int n = 0) : m_n(n) { } public: virtual int value() const { return m_n; } virtual ~A() { } protected: int m_n; }; class B : public A { public: B(int n = 0) : A(n) { } public: virtual int value() const { return m_n + 1; } }; int main() { const A a(1); const B b(3); const A *x[2] = { &a, &b }; typedef std::vector<A> V; V y; y.push_back(a); y.push_back(b); V::const_iterator i = y.begin(); std::cout << x[0]->value() << x[1]->value() << i->value() << (i + 1)->value() << std::endl; return 0; }
输出结果1413
数组X中保存的是对象的地址 在调用数组中的类型的时候会根据RTTI动态找到对象的函数
但是VECTOR容器中保存的是 父类对象A的元素 因为VECTOR是连续的内存地址, 他会把子类自动转成基类以便能封装进VECTOR中
8.
#include <iostream> class A { public: A(int n = 2) : m_i(n) { } ~A() { std::cout << m_i; } protected: int m_i; }; class B : public A { public: B(int n) : m_x(m_i + 1) , m_a(n) { } public: ~B() { std::cout << m_i; --m_i; } private: A m_x; A m_a; }; int main() { { B b(5); } std::cout << std::endl; return 0; }
输出结果为2531 先调用b的析构函数 然后再释放B的成员变量再调用父类的析构函数
虚函数表在类地址的最开始。
operator int () const重载类转换运算符号
比如
C c;
int a = (int)c;
9
.#include <iostream> #include <vector> class A { public: A(int n) : m_n(n) { } A(const A &a) : m_n(a.m_n) { ++m_copy_ctor_calls; } ~A() { ++m_dtor_calls; } private: int m_n; public: static int m_copy_ctor_calls; static int m_dtor_calls; }; int A::m_copy_ctor_calls = 0; int A::m_dtor_calls = 0; int main() { const A a = 2;//1 std::vector<A> v; v.reserve(2); 4000 v.push_back(a); v.push_back(1);//2 v.push_back(a);//3 std::cout << A::m_copy_ctor_calls << A::m_dtor_calls << std::endl; getchar(); return 0; }
输出结果为 5 3
运行到1时 调用构造函数不是拷贝构造函数
运行到2时 创建一个临时对象调用拷贝构造函数然后释放临时对象
3时容量不够 创建新的内存空间 复制旧的到新的 释放旧的
10. static const,virtual
class test { static fun() const {} static virtual gun() {} };
如果使用 是成员函数 如果使用 static 描述的 话,则不能同时为const 或者 virtual 因为,const 和 virtual内部包含了一个隐含的this指针。
未完待续..
相关文章推荐
- C++中对字符串或文件的操作函数,结尾的问题(持续补充)
- weblogic部署项目出现的一些问题(持续补充中……)
- 一些小问题的解决办法(持续补充更新)
- 关于Borland C++BuilderX的一些问题的回答
- 学渣学C++的一些问题及tips
- C++的一些小问题(一)
- C++ 写leetcode遇到的一些问题总结Reverse Words in a String
- c++一些 面试可能遇到的问题
- 0.Ubuntu下的一些小问题的解决方法(持续更新中)
- 软件设计思想的一些文章 (持续补充中)
- C++面试中不怎么注意和比较怪的一些问题
- 《Visual C++ 2010入门教程》系列三:关于C++的一些问题
- 一些数据库脚本(持续补充)
- 学习C++/CLI发现的一些问题,算不算Bug?
- (补充)点云压缩入门(一):pcc工程的编译所遇到的一些问题
- (持续更新)日积月累——iOS开发过程中遇到的一些小问题
- 使用VS编写ASP.NET(C#)遇到问题及解决(持续补充)
- private:c/c++ 我的一些容易出错的地方 =>持续更新
- 一些特别有趣的C++面试题(持续更新中)
- C++ 编程遇到的一些问题