const坑

C++中explicit的用法

 

C++提供了关键字explicit,可以阻止不应该允许的经过转换构造函数进行的隐式转换的发生,声明为explicit的构造函数不能在隐式转换中使用。

C++中, 一个参数的构造函数(或者除了第一个参数外其余参数都有默认值的多参构造函数), 承担了两个角色。 

1 是个构造;2 是个默认且隐含的类型转换操作符。

所以, 有时候在我们写下如 AAA = XXX, 这样的代码, 且恰好XXX的类型正好是AAA单参数构造器的参数类型, 这时候编译器就自动调用这个构造器, 创建一个AAA的对象。

这样看起来好象很酷, 很方便。 但在某些情况下, 却违背了程序员的本意。 这时候就要在这个构造器前面加上explicit修饰, 指定这个构造器只能被明确的调用/使用, 不能作为类型转换操作符被隐含的使用。
 

解析:explicit构造函数是用来防止隐式转换的。请看下面的代码:

 

 
  1. #include <iostream>

  2. using namespace std;

  3. class Test1

  4. {

  5. public :

  6. Test1(int num):n(num){}

  7. private:

  8. int n;

  9. };

  10. class Test2

  11. {

  12. public :

  13. explicit Test2(int num):n(num){}

  14. private:

  15. int n;

  16. };

  17.  
  18. int main()

  19. {

  20. Test1 t1 = 12;

  21. Test2 t2(13);

  22. Test2 t3 = 14;

  23.  
  24. return 0;

  25. }

 

 

编译时,会指出 t3那一行error:无法从“int”转换为“Test2”。而t1却编译通过。注释掉t3那行,调试时,t1已被赋值成功。

注意:当类的声明和定义分别在两个文件中时,explicit只能写在在声明中,不能写在定义中

 

 

22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222

C++ Explicit Constructors(显式构造函数)

  C++ 为类(Class)提供了许多默认函数。如果自己没有申明,编译器会为我们提供一个copy构造函数、一个copy assignment操作符一个析构函数。此外,如果没有申明任何构造函数,编译器会为我们申明一个default构造函数。很像下面的Empty类:

复制代码

1 class Empty{
2     public:
3         Empty();
4         Empty(const Empty &rhs);
5         ~Empty();
6         Empty& operator=(const Empty &rhs);
7 };

复制代码

   就像Effective C++说的,如果不想使用编译器自动生成的函数,就应该明确拒绝。

1.C++中的隐式构造函数

  如果c++类的其中一个构造函数有一个参数,那么在编译的时候就会有一个缺省的转换操作:将该构造函数对应数据类型的数据转换为该类对象。

2.Explicit Constructors显式构造函数

  为了避免上面提到的只有一个参数的构造函数采用的缺省转换操作,在构造函数前,使用Explicit 关键字修饰即可。

3.如下面的例子:

复制代码

 1 #include <iostream>
 2 using namespace std;
 3 class B{
 4     public:
 5         int data;
 6         B(int _data):data(_data){}
 7         //explicit B(int _data):data(_data){}
 8 };
 9 
10 int main(){
11     B temp=5;
12     cout<<temp.data<<endl;
13     return 0;
14 }

复制代码

  程序第11行,将int转换为B类型的对象,就是使用了隐式构造函数。因为B中存在一个只有一个参数的构造函数,且参数类型也是int。

  如果在构造函数前加explicit ,表示为显示构造函数,则第11行编译不能通过。因为这时,就没有隐式构造函数啦。

333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333

 

定义函数时,后面加const意义

2014年05月12日 10:01:02 ranyongqing 阅读数:3270 标签: c++ 更多

个人分类: C++

 const对象只能调用const成员函数。
  const对象的值不能被修改,在const成员函数中修改const对象数据成员的值是语法错误

  在const函数中调用非const成员函数是语法错误

 

任何不会修改数据成员的函数都应该声明为const类型。如果在编写const成员函数时,不慎修改了数据成员,或者调用了其它非const成员函数,编译器将指出错误,这无疑会提高程序的健壮性。
以下程序中,类stack的成员函数GetCount仅用于计数,从逻辑上讲GetCount应当为const函数。编译器将指出GetCount函数中的错误。
class Stack
{
  public:
void  Push(int elem);
int  Pop(void);
int GetCount(void)  const; // const成员函数
  private:
int m_num;
int m_data[100];
};

int Stack::GetCount(void)  const
{
++ m_num; // 编译错误,企图修改数据成员m_num
Pop(); // 编译错误,企图调用非const函数
return m_num;
}
const成员函数的声明看起来怪怪的:const关键字只能放在函数声明的尾部,大概是因为其它地方都已经被占用了。

444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444

C++类型转换详解--const_cast

2011年02月28日 15:49:00 lwbeyond 阅读数:31136 标签: c++ class 更多

个人分类: C/C++

一. 函数描述:
const_cast < type-id > ( expression )

主要是用来去掉const属性,当然也可以加上const属性。主要是用前者,后者很少用。

去掉const属性:const_case<int*> (&num),常用,因为不能把一个const变量直接赋给一个非const变量,必须要转换。

加上const属性:const int* k = const_case<const int*>(j),一般很少用,因为可以把一个非const变量直接赋给一个const变量,比如:const int* k = j;

 

二. 使用范围:
1. 常量指针被转化成非常量指针,转换后指针指向原来的变量(即转换后的指针地址不变)。

 
  1. class A

  2. {

  3. public:

  4. A()

  5. {

  6. m_iNum = 0;

  7. }

  8.  
  9. public:

  10. int m_iNum;

  11. };

  12.  
  13. void foo()

  14. {

  15. //1. 指针指向类

  16. const A *pca1 = new A;

  17. A *pa2 = const_cast<A*>(pca1); //常量对象转换为非常量对象

  18. pa2->m_iNum = 200; //fine

  19.  
  20. //转换后指针指向原来的对象

  21. cout<< pca1->m_iNum <<pa2->m_iNum<<endl; //200 200

  22.  
  23. //2. 指针指向基本类型

  24. const int ica = 100;

  25. int * ia = const_cast<int *>(&ica);

  26. *ia = 200;

  27. cout<< *ia <<ica<<endl; //200 100

  28. }

2. 常量引用转为非常量引用。

 

 
  1. class A

  2. {

  3. public:

  4.   A()

  5.   {

  6. m_iNum = 1;

  7.   }

  8.  
  9. public:

  10.   int m_iNum;

  11. };

  12.  
  13. void foo()

  14. {

  15.  
  16.   A a0;

  17.   const A &a1 = a0;

  18.   A a2 = const_cast<A&>(a1); //常量引用转为非常量引用

  19.  
  20.   a2.m_iNum = 200; //fine

  21.  
  22.   cout<< a0.m_iNum << a1.m_iNum << a2.m_iNum << endl; //1 1 200

  23. }

2. 常量对象(或基本类型)不可以被转换成非常量对象(或基本类型)。

 

[c-sharp] view plain copy

 

 

 

  1. void foo()  
  2. {  
  3.  //常量对象被转换成非常量对象时出错  
  4.  const A ca;  
  5.  A a = const_cast<A>(ca);  //不允许  
  6.   
  7.  const int i = 100;  
  8.  int j = const_cast<int>(i);  //不允许  
  9.   
  10. }  

记住这种转换只是开了一个接口,并不是实质上的转换。(其实也算是实质上的转换了,只不过表达上不允许这样写)

3. 添加const属性

 

[c-sharp] view plain copy

 

 

 

  1. int main(int argc, char ** argv_)   
  2. {  
  3.  int i = 100;  
  4.  int *j = &i;  
  5.  const int *k = const_cast<const int*>(j);  
  6.  //const int *m = j;   感觉和这样写差不多  
  7.   
  8.  //指的地址都一样  
  9.  cout <<i<<","<<&i<<endl; //100, 0012FF78  
  10.  cout <<*j<<","<<j<<endl; //100, 0012FF78  
  11.  cout <<*k<<","<<k<<endl; //100, 0012FF78  
  12.   
  13.  *j = 200;  
  14.  //*k = 200;   //error  
  15.   
  16.  return 0;  
  17. }  

 

三. 总结:
1. 使用const_cast去掉const属性,其实并不是真的改变原类类型(或基本类型)的const属性,它只是又提供了一个接口(指针或引用),使你可以通过这个接口来改变类型的值。也许这也是const_case只能转换指针或引用的一个原因吧。

 

2. 使用const_case添加const属性,也是提供了一个接口,来不让修改其值,不过这个添加const的操作没有什么实际的用途(也许是我认识太浅了)。

 

5555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555

C++类中const函数与非const函数的调用规则

2016年05月01日 17:04:52 langzi989 阅读数:3570

class EX{
    public:
        void constFunction() const;
};
  • 1
  • 2
  • 3
  • 4

如上所示,通过将类成员函数声明为const,以表示这个函数不可以修改类对象。任何不可以修改数据成员的函数都应该声明为const,如果在编写const成员函数时,不慎修改了数据成员, 或者调用了其他的非const函数,则此时编译器会指出错误,这样做的函数是提高了程序的健壮性。

在相同的函数参数及相同的名字的情况下,const函数与非const函数可以构成重载函数,但是const成员函数不能改变任何的非静态变量

const函数与非const函数的调用规则

  • const对象默认调用const成员函数,非const对象默认调用非const成员函数;
  • 若非const对象想调用const成员函数,则需要显示的转化,例如(const Student&)obj.getAge();
  • 若const对象想调用非const成员函数,同理进行强制类型转换const_cast < Student&>(constObj).getAge();(注意constObj一定要加括号)

当类中只有一种函数存在的情况
- 非const对象可以调用const成员函数或者非const成员函数
- const对象只能调用const成员函数,若直接调用非const成员函数编译器会报错。

55555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555

C++强制类型转换操作符 const_cast

const_cast也是一个强制类型转换操作符。《C++ Primer》中是这样描述它的:

1.将转换掉表达式的const性质。

2.只有使用const_cast才能将const性质性质转化掉。试图使用其他三种形式的强制转换都会导致编译时的错误。(添加const还可以用其他转换符,如static_const

3.除了添加const或删除const特性,使用const_cast符来执行其他任何类型的转换都会引起编译错误。(volatile限定符也包括,不过我不怎么了解,本文主要说const)

 

对于第一点,转换掉表达式的const性质,意思是可以改变const对象的值了吗?一开始我的确是这样子认为的,于是我敲出了如下的代码:

复制代码

int main()
{
    const int constant = 26;
    const int* const_p = &constant;
    int* modifier = const_cast<int*>(const_p);
    *modifier = 3;
    cout<< "constant:  "<<constant<<endl;
    cout<<"*modifier:  "<<*modifier<<endl;
    system("pause");
}

复制代码

然而程序并没有像预想的那样输出两个3,运行结果是这样的:

 

 

看来C++还是很厚道的,对声明为const的变量来说,常量就是常量,任你各种转化,常量的值就是不会变。这是C++的一个承诺。

那既然const变量的值是肯定不会发生变化的,还需要这个const_cast类型转化有何用?这就引出了const_cast的最常用用法:

如果有一个函数,它的形参是non-const类型变量,而且函数不会对实参的值进行改动,这时我们可以使用类型为const的变量来调用函数,此时const_cast就派上用场了。

例如:

 

复制代码

void InputInt(int * num)
{
    cout<<*num<<endl;
}
int main()
{
    const int constant = 21;
    //InputInt(constant); //error C2664: “InputInt”: 不能将参数 1 从“const int”转换为“int *”
    InputInt(const_cast<int*>(&constant));
    system("pause");
}

复制代码

 除此之外,还有另外一种情况const指针能够派上用场。如果我们定义了一个非const的变量,却使用了一个指向const值的指针来指向它(这不是没事找事嘛),在程序的某处我们想改变这个变量的值了,但手头只持有指针,这是const_cast就可以用到了:

复制代码

int main()
{
    int constant = 26;
    const int* const_p = &constant;
    int* modifier = const_cast<int*>(const_p);
    *modifier = 3;
    cout<< "constant:  "<<constant<<endl;
    cout<<"*modifier:  "<<*modifier<<endl;

    system("pause");
}

复制代码

 

 总结一下上文:const_cast绝对不是为了改变const变量的值而设计的!

        在函数参数的传递上const_cast的作用才显现出来。

>>>>>>>>>>>>>>>>>> >>>分割线>>>>>>>>>>>>>>>>>>>>>>>>>

const_cast中的未定义行为

 上面的第一段程序,输出变量constant与*modefier的地址后....

复制代码

int main()
{
    const int constant = 26;
    const int* const_p = &constant;
    int* modifier = const_cast<int*>(const_p);
    *modifier = 3;
    cout<< "constant:  "<<constant<<"  adderss:  "<< &constant <<endl;
    cout<<"*modifier:  "<<*modifier<<"  adderss:  " << modifier<<endl;

    system("pause");
}

复制代码

运行结果:

它们的地址是一样的,值却不同。具体原因我还是不大清除。在另外一些博客中看到, *modifier = 3; 这种操作属于一种“未定义行为”,也即是说操作结果C++并没有明确地定义,结果是怎样的完全由编译器的心情决定。对于未定义的行为,我们只能避免之。

关于const_cast是否安全的讨论

逛了一些网站,大致有如下观点:

复制代码

const_cast is safe only if you're casting a variable that was originally non-const. For example, if you have a function that takes a parameter of a const char *, and you pass in a modifiable char *, it's safe to const_cast that parameter back to a char * and modify it. However, if the original variable was in fact const, then using const_cast will result in undefined behavior.

也即是上文中所说的const_cast的二种适用情况。

复制代码

 

复制代码

I would rather use static cast for the adding constness: static_cast<const sample*>(this). When I'm reading const_cast it means that the code is doing something potentially dangerous, so i try to avoid it's use when possible.

也有人认为const_cast本身就给潜在危险带来可能,所以还是尽可能不用它了。
当需要给变量添加const属性时,使用更为安全的static_cast来代替const_cast。

这里附上讨论链接。const_cast是否安全?

 

 

777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777

 

const T、const T*、T *const、const T&、const T*& 的区别

原文地址: http://blog.csdn.net/luoweifu/article/details/45600415

这里的T指的是一种数据类型,可以是int、long、doule等基本数据类型,也可以是自己类型的类型class。单独的一个const你肯定知道指的是一个常量,但const与其他类型联合起来的众多变化,你是不是就糊涂了?下面我们一一来解析。

const T

定义一个常量,声明的同时必须进行初始化。一旦声明,这个值将不能被改变。

  1. int i = 5;
  2. const int constInt = 10; //正确
  3. const int constInt2 = i; //正确
  4. constInt = 20; //错误,常量值不可被改变
  5. const int constInt3; //错误,未被初

const T*

指向常量的指针,不能用于改变其所指向的对象的值。

  1. const int i = 5;
  2. const int i2 = 10;
  3. const int* pInt = &i; //正确,指向一个const int对象,即i的地址
  4. //*pInt = 10; //错误,不能改变其所指缶的对象
  5. pInt = &i2; //正确,可以改变pInt指针本身的值,此时pInt指向的是i2的地址
  6. const int* p2 = new int(8); //正确,指向一个new出来的对象的地址
  7. delete p2; //正确
  8. //int* pInt = &i; //错误,i是const int类型,类型不匹配,不能将const int * 初始化为int *
  9. int nValue = 15;
  10. const int * pConstInt = &nValue; //正确,可以把int *赋给const int *,但是pConstInt不能改变其所指向对象的值,即nValue
  11. *pConstInt = 40; //错误,不能改变其所指向对象的值

const int* 与int* const的区别

指针本身就是一种对象,把指针定义为常量就是常量指针,也就是int* const的类型,也可以写成int *const,声明时必须初始化。

  1. int nValue = 10;
  2. int* const p = &nValue;
  3. int *const p2 = &nValue;
  4. const int* 指针指向的对象不可以改变,但指针本身的值可以改变;int* const 指针本身的值不可改变,但其指向的对象可以改变。
  5. int nValue1 = 10;
  6. int nValue2 = 20;
  7. int* const constPoint = &nValue1;
  8. //constPoint = & nValue2; //错误,不能改变constPoint本身的值
  9. *constPoint = 40; //正确,可以改变constPoint所指向的对象,此时nValue1 = 40
  10.  
  11.  
  12. const int nConstValue1 = 5;
  13. const int nConstValue2 = 15;
  14. const int* pPoint = &nConstValue1;
  15. //*pPoint = 55; //错误,不能改变pPoint所指向对象的值
  16. pPoint = &nConstValue2; //正确,可以改变pPoint指针本身的值,此时pPoint邦定的是nConstValue2对象,即pPoint为nConstValue2的地址

const int* const 是一个指向常量对象的常量指针,即不可以改变指针本身的值,也不可以改变指针指向的对象。

  1. const int nConstValue1 = 5;
  2. const int nConstValue2 = 15;
  3. const int* const pPoint = &nConstValue1;
  4. //*pPoint = 55; //错误,不能改变pPoint所指向对象的值
  5. //pPoint = &nConstValue2; //错误,不能改变pPoint本身的值

const T&

对常量(const)的引用,又称为常量引用,常量引用不能修改其邦定的对象。

  1. int i = 5;
  2. const int constInt = 10;
  3. const int& rConstInt = constInt; //正确,引用及邦定的值都是常量
  4. rConstInt = 5; //错误,不能改变引用所指向的对象

允许为一个常量引用邦定一个非常量对象、字面值,甚至是表达式;引用的类型与引用所指向的类型必须一致。

  1. int i = 5;
  2. int& rInt = i; //正确,int的引用
  3. const int constInt = 10;
  4. const int& rConstInt = constInt; //正确,引用及邦定的值都是常量
  5. const int& rConstInt2 = rInt; //正确,用rInt邦定的对象进行赋值
  6. rInt = 30; //这时,rConstInt2、rInt、i的值都为30
  7. //rConstInt2 = 30; //错误,rConstInt2是常量引用,rConstInt2本身不能改变所指向的对象
  8.  
  9.  
  10. int i2 = 15;
  11. const int& rConstInt3 = i2; //正确,用非常量的对象为其赋值
  12. const int& rConstInt4 = i + i2; //正确,用表达式为其赋值,值为45
  13. i = 20; //此时i=20, rInt = 20, rConstInt4 = 45,说明rConstInt4邦定的是i + i2的临时变量
  14. const int& rConstInt5 = 50; //正解,用一个常量值为其赋值

const T*&与T *const&

指向常量对象的指针的引用,这可以分两步来理解:1.const T*是指向常量的指针;2.const T*&指向常量的指针的引用。

  1. const int nConstValue = 1; //常量对象
  2. const int nConstValue2 = 2; //常量对象
  3. const int* pConstValue = &nConstValue; //指向常量对象的指针
  4. const int* pConstValue2 = &nConstValue2; //指向常量对象的指针
  5. const int*& rpConstValue = pConstValue; //指向常量对象的指针的引用
  6. //*rpConstValue = 10; //错误,rpConstValue指向的是常量对象,常量对象的值不可改变
  7. rpConstValue = pConstValue2; //正确,此时pConstValue的值等于pConstValue2
  8. //指向常量对象的指针本身是对象,引用可以改变邦定对象的值
  9.  
  10. int nValue = 5;
  11. int nValue2 = 10;
  12. int *const constPoint = &nValue; //常量指针
  13. int *const constPoint2 = &nValue2; //常量指针
  14. int *const &rpConstPoint = constPoint; //对常量指针的引用,邦定constPoint
  15. //rpConstPoint = constPoint2; //错误,constPoint是常量指针,指针本身的值不可改变
  16. *rpConstPoint = 20; //正确,指针指向的对象可以改变

在函数中的应用

我们直接从需求出来,假设有这样一个数据结构:

  1. typedef struct __Data
  2. {
  3. int value;
  4. public:
  5. __Data()
  6. :value(0){}
  7. }Data;

1.希望传入一个对象,又不想让函数体修改这个对象。

方式<1>

  1. void Dealwith(const Data& data)
  2. {
  3. cout << data.value << endl;
  4. //data.value = 5; //错误,data是常量引用,不能改变其邦定的对象
  5. }

这种方式还有一个好处是只有在调用函数的时候会邦定对象,传递的是对象的引用,而不是对象,减少函数调用时对象赋值的花销。

方式<2>

  1. void Dealwith(const Data* pData)
  2. {
  3. cout << pData->value << endl;
  4. //pData->value = 5; //错误,pData是指向常量对象的指针,不能改变其指向的对象
  5. }

这种方式与void Dealwith(const Data& data)的功能相同

方式<3>

  1. Data g_data(20);
  2. void Dealwith(const Data*& pData)
  3. {
  4. cout << pData->value << endl;
  5. //pData->value = 5; //错误,pData邦定的是指向常量对象的指针,常量对象的指针不能改变其指向的对象
  6. pData = &g_data; //正确,pData是[指向常量对象的指针]的引用,引用可改变其邦定的对象
  7. }

调用如下:

  1. Data d(10);
  2. const Data* pData = &d;
  3. Dealwith(pData);
  4. cout << pData->value << endl; //此时pData->value为20,d.value还是10

这种方式函数未改变传入的对象的值,但可以返回另外一个对象的指针。注意返回的指针必须指向全局的对象,如果返回函数内定义的对象,退出函数作用域后,其指针将无效,这是非常危险的;如果Dealwith是成员函数,也可以返回指向成员的指针。

2.在类中的使用,返回一个类的成员,但不希望调用方修改这个成员。

方式<1>

  1. class MyData
  2. {
  3. public :
  4. MyData(std::string name, Data data)
  5. {
  6. m_name = name;
  7. m_data = data;
  8. }
  9.  
  10. const Data* GetData()
  11. {
  12. return &m_data;
  13. }
  14.  
  15.  
  16. private:
  17. std::string m_name;
  18. Data m_data;
  19. };

调用如下:

  1. MyData mydata("", Data(100));
  2. const Data* pData = mydata.GetData();
  3. cout << pData->value << endl; //pData->value = 100
  4. //pData->value = 50; //错误,pData是指向常量对象的指向,不能改变其指向对象的值

方式<2>

有人可能会问GetData也可以写成这样:

  1. const Data& GetData()
  2. {
  3. return m_data;
  4. }

这样的话,调用方常常容易写成这样:

  1. MyData mydata("", Data(100));
  2. Data data = mydata.GetData(); //这会有个赋值的过程,会把mydata.m_data赋给data
  3. cout << data.value << endl; //data.value = 100
  4. data.value = 50; //正确,data.value=50,但mydata.m_data.value还是100

这样调用时会有一个结果赋值的过程,如果Data是一个复杂的类,会有较大的开销,其效果与下面这种方式是一样的:

  1. Data GetData()
  2. {
  3. return m_data;
  4. }

当然,如果调用方这样使用是正确的:

  1. const Data& GetData()
  2. {
  3. return m_data;
  4. }
  1. MyData mydata("", Data(100));
  2. const Data& data = mydata.GetData(); //这会有个赋值的过程,会把mydata.m_data赋给data
  3. cout << data.value << endl; //data.value = 100
  4. //data.value = 50; //错误,data是一个对常量的引用,不能改变其邦定的对象

这对调用方的技术能力要求比较高,如果你是设计方,一定要尽量使接口简单易用。

方式<3>

如果你要传入一个Data进行一些处理,处理完后返回类的成员m_data,可如下实现:

  1. void DoSomething(const Data*& pData)
  2. {
  3. if (pData != NULL)
  4. {
  5. // doto: 这里实现你要处理的功能
  6. }
  7. pData = &m_data;
  8. }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值