C++隐式构造与显式构造

6 篇文章 0 订阅

<一> 

#include <iostream>
#include <string>
class Stock
{
public:
    /*explicit*/ Stock(const std::string& company) : _company(company), _share(0), _val(0.0) {}
    Stock() : _company(""), _share(0), _val(0.0) {}
    Stock(const std::string& company, long share, double val)
        : _company(company), _share(share), _val(val) {}
private:
    std::string _company;
    long _share;
    double  _val;
};

int main(){
    Stock food = Stock("hello",12,20.5);
    Stock food1("hello",12,20.5);
    Stock food2 = std::string("hi");
    std::cout <<"food : "<<&food<<", food1 : "<<&food1<<", food2 :  "<<&food2<< std::endl;
    return 0;
}

显式调用构造函数

显式调用构造函数意味着直接使用构造函数的参数来初始化对象。这通常在创建对象时发生,无论是通过声明一个变量还是通过使用new关键字动态分配内存。

Stock food = Stock("hello",12,20.5);
Stock food1("world",13,2.5);

每次创建类对象(甚至使用new动态分配内存)时,C++都使用类构造函数。下面是将构造函数与new一起使用的方法:

Stock *pstock =  new Stock("google",15,22.5);

隐式调用构造函数

隐式调用构造函数发生在将一个对象初始化为另一个对象,或者通过省略括号直接使用赋值语句时。对于构造函数,如果它只有一个参数(或所有参数除了一个都有默认值),那么它还可以作为转换构造函数,允许从一个类型隐式转换为对象类型。

Stock food = std::string("hi");

当使用explicit关键字时,阻止了隐式转换,要创建Stock对象,必须显式调用构造函数;

但如果没有explicit关键字,上述代码将隐式调用Stock(const string& company)构造函数。

<二>

class A
{
};

如果在编写类时没有显示的写出其构造函数,拷贝构造函数,析构函数,以及重载赋值操作符,编译器会在编译代码时,会为该类加上这些。

其形式大致如下:

class A
{
     A()
     {
     }

     A& operator =(const A& a)
     {
        memcpy(this, &a, sizeof(A));  //此处可能用问题,仅为表明不是浅拷贝
        return *this;
     }

     A(const A& a)
     {
       *this = a; //调用了赋值重载函数
     }

      ~A() // 注意在析构函数前不会加上virtual关键字
     {
     }
};


下面给出一些示例,注释部分说明了函数调用的情况:

void f()
{
 
   A a;     // A()构造函数被调用
   A b(a);  // A(const A& a)构造函数被调用 
   A c = a; // A(const A& a)构造函数被调用 
   b = c;   // A& operator = (const A& a)赋值操作符重载函数被调用 
}
 // 离开f()函数之前,a,b,c的析构函数被调用,释放资源

A c = a;

这句代码实际调用的是拷贝构造函数,而非赋值函数。

因此,我们可以构造出这样的代码。


class A
{
private:
    int *m_data;
    std::string ss;
public:
    A()
    {
        m_data = NULL;
    }
    A(int n)
    {
        m_data = NULL;
        if (n>0)
            m_data = new int[n];
    }
    A& operator =(const A& a)
    {
        memcpy(this, &a, sizeof(A));
        return *this;
    }
    virtual ~A()
    {
        if (NULL!=m_data)
        {
            delete [] m_data;
            m_data = NULL;
        }
    }
};
int main()
{
     A a = 3; // 将整数3赋值给一个对象
     return 0;
}

将整数3赋值给一个A类型对象a,然而以上代码可以编译通过。 -- 有点不合常理

这是由于“单参数构造函数”被自动型别转换(这是一个隐式转换)。

可以通过explicit关键字,阻止“以赋值语法进行带有转型操作的初始化”。如下所示:


class A
{
private:
     int *m_data;
     std::string ss;
public:
     A()
     {
         m_data = NULL;
     }
     explicit A(int n)
     {
         m_data = NULL;
         if (n>0)
             m_data = new int[n];
     }
     A& operator =(const A& a)
     {
     memcpy(this, &a, sizeof(A));
     return *this;
     }
     virtual ~A()
     {
         if (NULL!=m_data)
         {
              delete [] m_data;
              m_data = NULL;
         }
     }
 };
int main()
{
     // A a = 3; // 编译无法通过
     A b(3); // 可以编译通过
     return 0;
}

  • 3
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
C++ 中,隐式调用构造函数是指在某些情况下,编译器会自动调用构造函数来创建一个对象,而不需要程序员显式地调用构造函数。 例如,当我们定义一个类的对象时,编译器会自动调用该类的默认构造函数来创建对象。又例如,当我们用一个已有的对象初始化另一个对象时,编译器也会自动调用该类的拷贝构造函数来完成初始化。 下面是一个示例代码,演示了隐式调用构造函数的情况: ```c++ #include <iostream> using namespace std; class MyClass { public: int value; MyClass() { // 默认构造函数 cout << "default constructor called" << endl; value = 0; } MyClass(int n) { // 带参数的构造函数 cout << "constructor with int called" << endl; value = n; } MyClass(const MyClass& other) { // 拷贝构造函数 cout << "copy constructor called" << endl; value = other.value; } }; int main() { MyClass a; // 隐式调用默认构造函数 MyClass b = 10; // 隐式调用带参数的构造函数 MyClass c(a); // 隐式调用拷贝构造函数 MyClass d = b; // 隐式调用拷贝构造函数 return 0; } ``` 在上面的代码中,当我们定义对象 `a` 时,编译器会自动调用 `MyClass` 类的默认构造函数;当我们定义对象 `b` 时,由于使用了整数 `10` 进行初始化,编译器会自动调用 `MyClass` 类的带参数的构造函数;当我们定义对象 `c` 和 `d` 时,由于使用了已有的对象进行初始化,编译器会自动调用 `MyClass` 类的拷贝构造函数。 需要注意的是,当我们使用 `explicit` 关键字修饰一个构造函数时,就不能进行隐式调用构造函数了,只能使用显式调用构造函数

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值