#include "stdio.h"
#include <iostream>
using namespace std;
/*********************************************************/
/* 指针学习 */
/*********************************************************/
int fun(char *s)
{
int num = 0;
num += *s;
s++;
return num;
}
/*
因为"hello world!"是一个字符串常量,存放在静态数据区,
把该字符串常量存放的静态数据区的首地址赋值给了指针,
returnStr函数退出时,该该字符串常量所在内存不会被回收,
回为操作的一直是这个静态数据区,故能够通过指针顺利无误的访问。
*/
//char *returnStr()
//{
// char *p = "hello world!";
// return p;
//}
/*
"hello world!"是一个字符串常量,存放在静态数据区,没错,
但是把一个字符串常量赋值给了一个局部变量(char []型数组),
该局部变量存放在栈中,相当于把静态数据赋值给局部变量后,
操作的是这个局部变量。这是与前着最本质的区别,当returnStr函数退出时,栈要清空,
局部变量的内存也被清空了,所以这时的函数返回的是一个已被释放的内存地址,所以打印出来的是乱码。
*/
//char *returnStr()
//{
// char p[] = "hello world!";
// return p;
//}
//如果函数的返回值非要是一个局部变量的地址,那么该局部变量一定要申明为static类型
//char *returnStr()
//{
// static char p[] = "hello world!";
// return p;
//}
//
//int main()
//{
// char *str;
// str = returnStr();
// printf("%s\n", str);
//
// int b;
// char str1[] = "abcdefghijklmn";
// b = fun(str1); //在函数体内对s进行自加1,但是不意味着同时对str进行加1运算
//
// char a[20] = "you are a girl";
// cout << "整个数组的首地址:" << &a << endl;
// cout << "首元素的首地址:" << &a[0] << endl;
// cout << "首元素的首地址:" << a << endl;
// cout << "下一个元素的首地址:"<< &a[1] << endl;
//
// int *p1[10]; //[]等级高 所以是指针数组,数组中存放的都是int*的指针
// int b1[10];
// int(*p2)[10] = & b1; //()优先级高于[],所以是数组指针,也就是指针指向的是一个int型的数组
//
// int *ptr = (int*)a;
// cout << ptr << endl; //ptr = &a = 002DFC48
// ptr += 5; //指针加上5 编译器是将PTR的值加上5*sizeof(int) = 5*4 =20
// cout << ptr << endl;
//
//
// system("pause");
// return 0;
//}
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
/*********************************************************/
/* 函数返回值的问题 */
/*********************************************************/
//#include <stdio.h>
//
返回的是局部变量的地址,该地址位于动态数据区,栈里
//char *s1()
//{
// char p[] = "Hello world!";
// printf("in s1 p=%p\n", p);
// printf("in s1: string's address: %p\n", &("Hello world!"));
// return p;
//}
//
返回的是字符串常量的地址,该地址位于静态数据区
//char *s2()
//{
// char *q = "Hello world!";
// printf("in s2 q=%p\n", q);
// printf("in s2: string's address: %p\n", &("Hello world!"));
// return q;
//}
//
返回的是静态局部变量的地址,该地址位于静态数据区
//char *s3()
//{
// static char r[] = "Hello world!";
// printf("in s3 r=%p\n", r);
// printf("in s3: string's address: %p\n", &("Hello world!"));
// return r;
//}
//
//int main()
//{
// char *t1, *t2, *t3;
// t1 = s1();
// t2 = s2();
// t3 = s3();
// printf("in main:");
// printf("p=%p, q=%p, r=%p\n", t1, t2, t3);
// printf("%s\n", t1);
// printf("%s\n", t2);
// printf("%s\n", t3);
// system("pause");
// return 0;
//}
//函数返回时,先将返回值存入寄存器,
//然后释放局部变量空间,最后return. fn()返回j其实是返回j的一个拷贝出来。
//int fn()
//{
// int j= 3;
// return j;
//}
//char* test()
//{
// char a[] = "hello "; //乱码
// //char *a = "hello "; //ok
// //static char a[] = "hello"; //ok
// return a;
//}
//int main(int argc, char* argv[])
//{
// printf("%d\n", fn());
// printf("%s\n", test());
// system("pause");
// return 0;
//}
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
/*********************************************************/
/* 重载覆盖和隐藏 */
/*********************************************************/
//( 1)函数 Derived::f(float)覆盖了 Base::f(float)。
//
//( 2)函数 Derived::g(int)隐藏了 Base::g(float),而不是重载。!!!!!!!!!!!!!!!!!!!!!!!!
//
//( 3)函数 Derived::h(float)隐藏了 Base::h(float),而不是覆盖。
//class Base
//{
//public:
// virtual void f(float x)
// {
// cout << "Base::f(float) " << x << endl;
// }
// void g(float x)
// {
// cout << "Base::g(float) " << x << endl;
// }
// void h(float x){ cout << "Base::h(float) " << x << endl; }
//};
//class Derived : public Base
//{
//public:
// virtual void f(float x)
// {
// cout << "Derived::f(float) " << x << endl;
// }
// void g(char x)
// {
// cout << "Derived::g(int) " << x << endl;
// }
// void h(float x){ cout << "Derived::h(float) " << x << endl; }
//};
//
//void main(void)
//{
// Derived d;
// Base *pb = &d;
// Derived *pd = &d;
// // Good : behavior depends solely on type of the object
// pb->f(3.14f); // Derived::f(float) 3.14
// pd->f(3.14f); // Derived::f(float) 3.14
// // Bad : behavior depends on type of the pointer
// pb->g(3.14f); // Base::g(float) 3.14
// pd->g(3.14f); // Derived::g(char) 3 (surprise!) 隐藏掉了 只能调用继承类函数
// // Bad : behavior depends on type of the pointer
// pb->h(3.14f); // Base::h(float) 3.14 (surprise!)
// pd->h(3.14f); // Derived::h(float) 3.14
//}
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
/*********************************************************/
/* 友元 */
/*********************************************************/
//class MyClass
//{
//public:
// MyClass(string name)
// {
// m_name = name;
// }
//
// //声明一个友元函数
// friend void Display(MyClass &mycalss);
// friend ostream& operator<< (ostream &os, MyClass &ob);
//protected:
// string m_name;
//};
//
定义这个友元函数
不要写成 void MyClass::Display(MyClass &mycalss)
//void Display(MyClass &mycalss)
//{
// cout << "Access Protected data : "<< mycalss.m_name << endl;
//}
//
测试
//int main(int argc, char* argv[])
//{
// MyClass test("Class A");
//
// Display(test);
//
// return 0;
//}
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
//#include <iostream>
//using namespace std;
//
//class Base{
//public:
// virtual ~Base() { cout << "~B" << endl; }
//};
//
//class Derived :public Base{
//public:
// ~Derived() { cout << "~D" << endl; }
//};
//
//int main()
//{
// Base *b = new Derived; //注意这里
// delete b; //先调用派生类析构 再调用子类析构
//}
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
/*********************************************************/
/* 拷贝构造函数 */
/*********************************************************/
/*
对象以值传递的方式传入函数参数
调用g_Fun()时,会产生以下几个重要步骤:
(1).test对象传入形参时,会先会产生一个临时变量,就叫 C 吧。
(2).然后调用拷贝构造函数把test的值给C。 整个这两个步骤有点像:CExample C(test);
(3).等g_Fun()执行完后, 析构掉 C 对象。
*/
//class CExample
//{
//private:
// int a;
//
//public:
// //构造函数
// CExample(int b)
// {
// a = b;
// cout << "creat: " << a << endl;
// }
//
// //拷贝构造
// CExample(const CExample& C)
// {
// a = C.a;
// cout << "copy" << endl;
// }
//
// //析构函数
// ~CExample()
// {
// cout << "delete: " << a << endl;
// }
//
// void Show()
// {
// cout << a << endl;
// }
//};
//
全局函数,传入的是对象
//void g_Fun(CExample C)
//{
// cout << "test" << endl;
//}
//
//int main()
//{
// CExample test(1);
// //传入对象
// g_Fun(test);
//
// return 0;
//}
//对象以值传递的方式从函数返回,也是调用拷贝构造函数
//class CExample
//{
//private:
// int a;
//
//public:
// //构造函数
// CExample(int b)
// {
// a = b;
// }
//
// //拷贝构造
// CExample(const CExample& C)
// {
// a = C.a;
// cout << "copy" << endl;
// }
//
// void Show()
// {
// cout << a << endl;
// }
//};
//
全局函数
//CExample g_Fun()
//{
// CExample temp(0);
// return temp;
//}
//
//int main()
//{
// g_Fun();
// return 0;
//}
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
/*
默认的拷贝构造函数不能对static变量进行处理,需要手动添加
*/
//class Rect
//{
//public:
// Rect() // 构造函数,计数器加1
// {
// count++;
// cout << "constrctor" << endl;
// }
// ~Rect() // 析构函数,计数器减1
// {
// count--;
// cout << "destrctor" << endl;
// }
// static int getCount() // 返回计数器的值
// {
// return count;
// }
//private:
// int width;
// int height;
// static int count; // 一静态成员做为计数器
//};
//class Rect
//{
//public:
// Rect() // 构造函数,计数器加1
// {
// count++;
// }
// Rect(const Rect& r) // 拷贝构造函数
// {
// width = r.width;
// height = r.height;
// count++; // 计数器加1
// }
// ~Rect() // 析构函数,计数器减1
// {
// count--;
// }
// static int getCount() // 返回计数器的值
// {
// return count;
// }
//private:
// int width;
// int height;
// static int count; // 一静态成员做为计数器
//};
//int Rect::count = 0; // 初始化计数器
//
//int main()
//{
// Rect rect1;
// cout << "The count of Rect: " << Rect::getCount() << endl;
//
// Rect rect2(rect1); // 使用rect1复制rect2,此时应该有两个对象
// cout << "The count of Rect: " << Rect::getCount() << endl;
//
// return 0;
//}
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
/*
默认拷贝构造函数不能对动态分配空间,需要手动重写拷贝构造函数
*/
class Rect
{
public:
Rect() // 构造函数,p指向堆中分配的一空间
{
p = new int(100);
}
~Rect() // 析构函数,释放动态分配的空间
{
if (p != NULL)
{
delete p;
}
cout << "deconstrctor" << endl; //析构一次 但是同一个内存
}
private:
int width;
int height;
int *p; // 一指针成员
};
//class Rect
//{
//public:
// Rect() // 构造函数,p指向堆中分配的一空间
// {
// p = new int(100);
// }
// Rect(const Rect& r)
// {
// width = r.width;
// height = r.height;
// p = new int; // 为新对象重新动态分配空间
// *p = *(r.p);
// }
// ~Rect() // 析构函数,释放动态分配的空间
// {
// if (p != NULL)
// {
// delete p;
// }
// cout << "deconstrctor" << endl; //重新分配空间 析构两次
// }
//private:
// int width;
// int height;
// int *p; // 一指针成员
//};
//int main()
//{
// Rect rect1;
// Rect rect2(rect1); // 复制对象
// return 0;
//}
/*
验证const如何区分重载
1.按值传递时,对用户而言,这是透明的,用户不知道函数对形参做了什么,
在这种情况下重载是没有意义的,所以规定不能重载。
2.当指针或引用被引入时,用户就会对函数的操作有了一定的了解,
不在是透明的,这时重载是有意义的,所以规定可以重载。
*/
//class A
//{
//public:
// void f(int i){ cout << "无const" << endl; }
// void f(int i)const{ cout << "有const" << endl; }
// //void f(const int i){ cout << "const在参数中" << endl; } //没有意义,不允许重载
// void f(int&){ cout << "int&" << endl; }
// void f(const int&){ cout << "const int&" << endl; }
//};
/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
//void test_static()
//{
// static int Temp = 1;
// Temp++;
// printf("Temp is :%d\n", Temp);
//}
//
//int main(int argc, char *argv[])
//{
// A a;
// cout << a.c1 << endl;
//
// int i = 0;
// for (i = 0; i <= 4; i++)
// {
// test_static();
// }
//
// system("pause");
//}
20170810
最新推荐文章于 2018-08-10 09:52:00 发布