C++小问题以及解析

1. 类函数中访问参数的私有变量

例如 String(constString &other)

{

m_data=other.x;//x是String类的私有成员 

}

 

因为拷贝构造函数是放在本身这个类里的,而类中的函数可以访问这个类的对象的所有成员,当然包括私有成员了,访问控制是针对类而言的,而不是对象。

String(const String &other)

{

m_data=other.x;//x是String类的私有成员

}

 

引用参数对象也是String类的,所以没问题。

 

 

2. 函数声明当作对象定义

 

struct Test

{

         Test(int){}

         Test(){}

         voidfun(){cout<<"func"<<endl;}

};

int main()

{

         Test a(1);

         Test b(); //此处是一个函数声明,返回值为Test类型,而不是对象定义!

         Test b1; //对象定义

         Test *c = new Test();

         Test *d = new Test(2);

         a.fun();

         b.fun(); //error! 编译不过

         c->fun();

         d->fun();

        

       system("pause");

        return 1;

}

 

 

2.CMystring s4 = "abc"; 

// 等价于CMystring s4= CMystring("abc"); 但devc++中测试时,没有执行拷贝构造函数,只// 执行了CMystring( const char* str ); 原因是编译器对其优化了

 

class String

{

public:

    String ( const char* p ); // 用C风格的字符串p作为初始化值

    //…

}

 

String s1 = “hello”; //OK 隐式转换,等价于String s1 = String(”hello”)

 

 

类似问题解决:

#include <iostream>

using namespace std;

 

class A

{

    public:

           A(int i) : val(i){cout << "A():" << this << endl; };

           int val;

           A& operator=(const A& a )

           {

                         cout<< "= func:" << &a << endl;

                         cout<< "= func:" << this << endl;

                         return*this;

                        

           }

           A(const A&) :val(5){cout << "copy func"; }

          

};

 

 

int main()

{

   

    A a = 3;  // 本来是先调用 A(int )构造一个临时对象,然后 调用拷贝构造函数构造 a

              // 这里是直接调用 A(int)构造 a,c++标准的原话,大意

              // 为:当一个隐式声明的对象被拷贝到一个同类型的对象时,编译器可以选择跳过拷贝的过程而直接将拷贝的终

              // 点对象作为构造的对象,而不必考虑因此带来的任何副作用。

    cout << &a <<endl;

    cout << a.val <<endl; // 输出3

 

    system("pause");

    return 1;

}

 

 

3. char* ,int,float隐式转化为bool类型

 

#include <iostream>

#include <stdio.h>

using namespace std;

int main()

{

   

    char *p = "jhk"; //char *p = "";也会输出1 char *p =NULL;会输出0

    bool falg = p;

    cout << falg;

    system("pause");

    return 1;

}

 

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

{

    int a = 1;

    char * b = "wo";

    float c = 1.1;

 

    bool x;

    x = a;

    x = b;

    x = c;

    system("pause");

    return 0;

}

总结:int,char*,float确实都可以隐式转化成bool而不会有任何警告,导致出现问题很不容易发现,这里在重载函数的时候确实需要万分注意。

 

 

4.枚举常量:

// 类CT的大小为4

class CT

{

public:

    enum

    {

        SIZE1 = 100, // 枚举常量不占用内存空间,枚举它的隐含数据类型是int,不能表示浮点数,如PI = 3.1415

        SIZE2 = 200

    };

 

private:

    int m_Int;

};

 

5. 常量问题:

        const int cstInt = 0;

    cout << sizeof(cstInt)<< endl;

    //cstInt = 1;  // 常量不能修改,编译时进行检测

    cout << cstInt <<endl;

 

    // int* pInt = &cstInt; //将编译通不过

    int* pInt = (int*)&cstInt;// C++强制转换

    *pInt = 3;  // 这样将可以修改常量cstInt对应内存空间的值了,呵呵

    cout << *pInt <<endl;  // 输出3

    cout << cstInt <<endl; // 为什么还是输出0呢?因为在编译时把所有用到cstInt的地方都改成了0,在后面改他的值是没有用的

 

    //用普通变量的时候,汇编语句是

    //  mov eax,xxxValue

    //  push eax

    //  call xxxfunction

    //  用const变量的时候是

    //  push 0

    //  call xxxfunction

 

6. 返回值以及extern问题:

// #include "test1.h" 使用test1头文件也可以

#include "test.h"

 

// .c文件,c++编译器将以c来编译此文件

int Add( int a, int b )

{

    // 返回临时变量,如果int有构造函数,将调用构造函数,临时变量保存在此函数之外,节约了拷贝,但是此句将编译通不过,

    // 因为当前文件是.c文件,而c语言中没有类的概念,所以也就没有构造函数的概念,所以此句通不过

    //return int(a + b);

    return a+b;

    // return a+b;  // 将把a+b的值拷贝到外部临时变量中

}

 

// 下面函数将编译通不过,因为extern是表明函数和全局变量作用范围的关键字

// int TestExtern()

// {

// extern int nInt;

// nInt = 10;

// int num = nInt;

// //int nInt = 1;

//

// return num;

// }

 

7. 释放类对象和内置类型的空间:

 

2.

int *p = new int[5];

//最好用delete[]p;  对于内置数据类型,如int char float等,可以用delete p代替delete []p;

delete p;

 

// 因为申请内存时,提供了确定的大小,释放时已经知道要释放多少内存,如本例是5个int大小

// 对于类,结构体等,释放数组时要使用delete []p,因为申请的内存在运行时可能会变化,如类中

// 若有char *p;一个数据变量,在运行中有p = new char[5];,其类内存变化了,要使用delete []p

// 告诉编译器释放的是一个数组,以便释放时调用其析构函数来释放动态申请的空间。

 

 

8. 一个内存分配导致的错误

#include <stdio.h>

#include <stdlib.h>

 

int main()

{

 

      int m = 0;

      int n = 3;

 

      char pch[] = "";

      scanf( "%s", pch);

      printf( "%s\n\n",pch );

 

      printf( "%d\n", n); // n不为3了

 

      getchar();

      getchar();

     

      return 1;

}

 

解释:

pch[]没给大小,而且后面的赋值也是空串

它指向一个存不了数据的空间

即空间大小除了一个\0以为,没数据

pch指向的只有一个'\0'字符,输入时pch所指向的是堆栈中的内存,所以会覆盖n,导致n改变

 

#include <stdio.h>

 

void main()

{

    int i,j,a[2] ;

    for( i = 0 ; i <= 2 ; i++  )

        scanf("%d",&a[i]); // 数组越界,但不会报错 a+3是j的地址

    printf("%d\n",j);  // j为最后输入的值

}

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值