c++的studylog

今天在看c++的视频学习的时候,有个问题很不解

  代码如下:

   

#include <iostream>
using namespace std;
class A{
    public:
      A(int i){ cout<<"执行构造函数!\n";x=i;}
      A(A&a){ cout<<"执行复制构造函数!\n";}
      ~A(){cout<<"析构函数!";}
      int get(){ return x;}
    private:
      int x;
};

A func(){
    cout<<"跳转!"<<endl;
    A a(34);
    cout<<"对象a的地址:"<<&a<<endl;
    return a;

}
int main(){
     A &r=func();
    cout<<"对象a的副本地址:"<<&r<<endl;
    cout<<r.get()<<endl;
    return 0;
}

第21行代码编译报错:

|error: invalid initialization of non-const reference of type 'A&' from a temporary of type 'A'|
||=== Build finished: 1 errors, 0 warnings ===|

但是学习的视频代码没有错误,代码编译正常。

但在这行代码之前加个 const就可以通过编译。

即:const A &r=func(); //临时对象是const的



很不解的是视频上的是a的地址和a的副本地址不一样,即a的副本对象是调用构造函数创建的对象a的一个副本,也就是 说 两个对象不是一样的对象。

但是我在编译这段代码的时候,a和a的副本地址是一样的,析构函数也是输出一次。


注解:

函数返回一个对象值时,会产生临时对象,函数中的返回值会以值拷贝的形式拷贝到被调函数栈中的一个临时对象。

栈中对象都是系统自动分配的,堆中对象是delete删除的。


常量和引用只能初始化,不能赋值;


构造函数的初始化:

class rectangle{
   public:
       rectangle(int a,int b):length(a),total(b){}
    private:
       const int length;
       int &total;
};

#include <iostream>
using namespace std;

class A{
   public:
       A(){}
       //A(A&one){n=one.n;m=one.m;}
       A(int a,int b){m=a;n=b;}
       void print(){
          cout<<n<<m;
       }
    private:
       int m;
       int n;
};
int main(){
   A a(2,4);
   a.print();
   cout<<"\n";
   A &c=a;
   A b(c); //完成两个对象之间成员的拷贝。即 c拷贝到b
   b.print();

    return 0;
}


2013-06-02:

#include "mvk.h"
using namespace std;

class A{
   public:
       A(){ x=new int;*x=5;}
       ~A(){ delete x;x=NULL;}
       void print() const{
          cout<<*x<<endl;
       }
       void set(int i){*x=i;}

    private:
       int *x;
};
int main(){
    A *a=new A();
    cout<<"a:"<<endl;
    a->print();

    cout<<"b:"<<endl;
    A b(*a);//这里两个对象的复制,可以写成:A b=*a; A*b=a;

    b.print();

    return 0;
}

由于a和b都指向同一块内存堆,当delete a后,a指向的堆删除了,b指针指向的内存区域也就不存在了,这时程序会报错。


2013-07-24

刚学c++的时候,对指针的表现方式很模糊,有时会产生矛盾的理解,比如说举个简单的例子来说:


#include <iostream>
using namespace std;

void reset(int *p){
   *p=0;

}
int main (int argc ,const char *argv[]){
    cout<<"begin:"<<endl;
    int i=32;
    int *p= &i;
    cout<<"p的地址:"<<p<<endl;

    reset(p);
    p=0;
     cout<<"p的地址:"<<p<<endl;

}

reset函数的参数int  *p是个指针,调用的时候reset(p),有时候会这样理解why调用的reset不是reset(*p)呢(当然reset(*p)的调用方式是错误的),

而是reset(p)呢,其实可以这样理解,reset函数参数int   *p可以写成int*   p,int*是一种整型指针类型,p是变量名,即指针。


2013-07-25


 

typedef char* pStr;


char string[4] = "abc";


 const char* p1 = string;// char* const p1=string;


const pStr p2 = string;


p1++; //这个是对的,如果换成注释的,那就不可以了。


p2++;//error

const pStr p2和const int x本质上没有区别,都是对变量进行只读限制,只不过此处变量p2的数据类型是我们自己定义的而不是系统固有类型而已。因此,const pStr p2的含义是:限定数据类型为char *的变量p2为只读,因此p2++错误。



函数指针的用法:

代码【1】

代码【1】
#include <iostream>
using namespace std;
int  Max(int a, int b)
{
    return a > b ? a : b;
}


typedef int (*pFun)(int, int);
pFun max_=&Max;//或者pFun max_=Max;


int main(int argc ,const char* argv[]){
    int a = 3;
    int b = 4;

    cout<<"Test function pointer: "<<endl;
    cout<<(*max_)(a,b)<<endl;//或者cout<<(max_)(a,b)<<endl;
  
}


代码【2】

#include <iostream>
using namespace std;

int  Max(int a, int b)
{
    return a > b ? a : b;
}

int  Min(int a, int b)
{
    return a < b ? a : b;
}

/*通用接口函数,实现对其他函数的封装*/
int   Result(pFun fun, int a, int b)
{
    return (*fun)(a, b);//(fun)(a,b)也可以
}

int main(int argc ,const char* argv[]){
    int a = 3;
    int b = 4;
    cout<<"Test function pointer: "<<endl;
    cout<<"The maximum number between a and b is "<<Result(Max, a, b)<<endl;
    cout<<"The minimum number between a and b is "<<Result(Min, a, b)<<endl;
}

1)  函数指针的初始化

函数如下:

1  int CompareString( const  string& str1,  const  string& str2)
2 {
3      return str1.compare(str2);  

4 }

函数的初始化有两种方式:

第一种,也是最普遍的方式:

1  int (*CompareFunction)( const  string&,  const  string&) = CompareString;

第二种,是使用typedef定义函数类型,这种写法有助于对代码的理解:

1  typedef  int (*CompareFunctionType)( const  string&,  const  string&);
2 CompareFunctionType CompareFunction = CompareString;

2)  函数指针赋值。

函数名可以理解为该类型函数的指针。当然,取地址操作符作用于函数名上也能产生指向该类型函数的指针。也就是说下面两种赋值都是可行的:

1 CompareFunctionType CompareFunction = CompareString;
2 CompareFunctionType CompareFunction =  &CompareString;

3)  函数调用。

无论是用函数名调用,还是用函数指针调用,还是用显式的指针符号调用,其写法是一样的:

1 CompareString( " abc "" cba ");
2 CompareFunction( " abc "" cba ");
3  (*CompareFunction)( " abc " " cba " );


参考:http://www.cnblogs.com/AnnieKim/archive/2011/11/20/2255813.html


代码【3】

#include <iostream>

using namespace std;

class Base {
     public:
            virtual void f() { cout << "Base::f" << endl; }
            virtual void g() { cout << "Base::g" << endl; }
            virtual void h() { cout << "Base::h" << endl; }

};



int main (int argc ,const char *argv[]){

   typedef void(*Fun)(void);

            Base b;

            Fun pFun = NULL;

            cout<<&b<<endl;
            cout<<(int*)*((int*)(&b))<<endl;
            cout << "虚函数表地址:" << (int*)(&b) << endl;
            cout << "虚函数表 — 第一个函数地址:" << (int*)*(int*)(&b) << endl;

            // Invoke the first virtual function
            pFun = (Fun)*((int*)*(int*)(&b));//不理解(Fun)*的含义
            pFun();

}
函数指针参考: http://blog.jobbole.com/44639/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值