是否可以在C++中不使用转换构造函数的情况下进行类型转换?

问题描述:

对于已经有一个显式构造函数接受单个参数的用户定义类,是否有可能以某种其他方式实现Conversion Constructor行为。是否可以在C++中不使用转换构造函数的情况下进行类型转换?

有关类别 -

class Foo 
{ 
    explicit Foo(int size); 
} 

是否有可能使此代码仍然有效 -

Foo a = 3; 
+2

不是,或者让构造函数非''explicit',或者你必须写'Foo a(3);'或'Foo a = Foo(3);' – Barry

+0

为什么你需要另一种方式?只要使用该语言已经可以做的事情。 –

+0

@The PC Luddite该构造函数已被用于其他目的.. – g6799821

是。的class Foo定义之后简单地写:

struct Bar { 
    Bar(int){}; 
}; 
#define Foo Bar 

和所需的代码会编译,并调用转换构造函数。

这似乎是一个坏主意,但它是可能的。

+0

这没有意义。 'Foo'是一个需要用'5'值初始化的类。 OP不需要'int'的别名。 –

+0

OP询问'Foo a = 3'是否可以有效:上面说明它是有效的。毫无意义,但这是一个问题的挑战。使用'explicit Foo(int)'可以使'Foo f = 5;'编译成为可能。 – Yakk

+0

@ Yakk7他问“Foo a = 3”是否可以在“转换构造函数”的上下文中有效。这不是一个构造函数。这是一个宏观。 –

不,这是不可能的。构造函数只能用于一个目的,并且不能有两个具有相同参数的构造函数来执行不同的操作。

如果Foo是一个int的数组就像你在你的评论中所说的那样,它可能是一个糟糕的设计选择,有一个构造函数带有一个填充数组第一个元素的参数。由于以下几个原因,它的设计很糟糕:

  1. 你怎么知道当Foo被初始化时数组大小是多少?即使有一些默认值,它也是一个非显而易见的实现。
  2. 这很混乱。设计代码时应该使用element of least surprise。我从来没有见过一个包装数组的类有一个填充它的第一个元素的单个参数构造函数。它没有任何意义。

在C++ 11中,可以使用初始化程序列表作为第二个构造函数。

#include <initializer_list> 
#include <cstring> 

class Foo { 
    private: 
     int* arr; 
     size_t len; 
    public: 
     explicit Foo(size_t size) 
      : len(size) { 
      arr = new int[len]; 
     } 

     Foo(std::initializer_list<int> list) // Initializer list constructor 
      : len(list.size()) { 
      arr = new int[len]; 
      size_t pos = 0; 
      for(auto it = list.begin(), e = list.end(); it != e; ++it) { 
       arr[pos++] = *it; // copy the list into your array 
      } 
     } 

     Foo(const Foo& other) 
      : len(other.len) { 
      arr = new int[len]; 
      memcpy(arr, other.arr, len * sizeof*arr); 
     } 

     Foo& operator=(const Foo& other) { 
       if (&other != this) { 
        delete[] arr; 
        len = other.len; 
        arr = new int[len]; 
        memcpy(arr, other.arr, len * sizeof*arr); 
       } 
       return *this; 
     } 

     ~Foo() { 
      delete[] arr; 
     } 
}; 

这样的话,你可以使用这样的初始化1元:

Foo a = { 3 }; 

或者这样创建具有 “3” 整型数组:

Foo a(3); 

甚至立即创建整个阵列:

Foo a = { 3, 7, 10, 12, 13 }; 

我意识到你只是使用了一个int数组作为例子,但这只是表明通常有更好的方法来设计代码,然后提出你的建议。