简体   繁体   English

是否可以有一个带有 1 个未声明类型的输入参数的构造函数?

[英]Is it possible to have a constructor with 1 input parameter of undeclared type?

Here is what I an trying to do:这是我想做的事情:

  1. Class with two objects ( string myStr and int myInt ) Class 有两个对象( string myStrint myInt

  2. Constructor takes in 1 parameter (data type not fixed).构造函数接受1 个参数(数据类型不固定)。

  3. If parameter is string: myStr = parameter; myInt = parameter.length(); If参数是字符串: myStr = parameter; myInt = parameter.length(); myStr = parameter; myInt = parameter.length();

  4. If parameter is int: myInt = parameter; myStr = "0000...0" If参数是 int: myInt = parameter; myStr = "0000...0" myInt = parameter; myStr = "0000...0" (string of length "parameter", set by for loop) myInt = parameter; myStr = "0000...0" (长度为“参数”的字符串,由 for 循环设置)

  5. Else : cout << "Error"; Elsecout << "Error";

Is it possible to do what I am describing in line 2?是否可以做我在第 2 行中描述的事情?

I've managed to do some workarounds using only strings and converting data types (able to do this when imposing an artificial lower bound for length of myStr ) however this is causing me other issues further down the line.我已经设法仅使用字符串和转换数据类型(在为myStr的长度施加人为下限时能够做到这一点)做一些变通方法,但这会导致我进一步的其他问题。

Is it possible to have a constructor with 1 input parameter of undeclared type?是否可以有一个带有 1 个未声明类型的输入参数的构造函数?

Technically, you can have variadic parameters which allows unspecified number of arguments of unspecified types.从技术上讲,您可以使用可变参数,允许未指定数量的未指定类型的 arguments。 But I recommend against using it.但我建议不要使用它。

The types of all other parameters must be declared.必须声明所有其他参数的类型。

  • If parameter is string: myStr = parameter;如果参数是字符串: myStr = parameter; myInt = parameter.length(); myInt = parameter.length();

  • If parameter is int: myInt = parameter;如果参数是 int: myInt = parameter; myStr = "0000...0" (string of length "parameter", set by for loop) myStr = "0000...0"(长度为“参数”的字符串,由 for 循环设置)

You can easily achieve this using two constructors instead of one.您可以使用两个构造函数而不是一个构造函数轻松实现这一点。 One that accepts a string and another that accepts an integer.一个接受字符串,另一个接受 integer。

Here is an example of the ideas discussed, overloaded constructors and a templated constructor (mostly just for educational purposes).这是讨论的想法的示例,重载构造函数和模板化构造函数(主要用于教育目的)。 I think you see why the overloads are considered to be a bit more practical for this case:)我想你明白为什么在这种情况下重载被认为更实用:)

#include <iostream>
#include <string>
#include <type_traits>

//-------------------------------------------------------------------------------------------------
// class wit overloaded constructorss

class my_class_t
{
public:
    explicit my_class_t(const std::size_t& size) :
        m_size{ size }
    {
    }

    explicit my_class_t(const std::string& string) :
        m_string{ string },
        m_size{ string.size() }
    {
    }

    // any other type of parameter to the constructor will just not compile

    std::size_t size() const
    {
        return m_size;
    }

private:
    std::string m_string;
    std::size_t m_size;

};

//-------------------------------------------------------------------------------------------------
// class with templated constructor
// it is a bit more complicated :)

class my_class_template_constructor_t
{
public:
    // this is the syntax for a function that can accept a parameter of any type
    template<typename type_t>
    explicit my_class_template_constructor_t(const type_t& value)
    {
        // select code based on some compile time logic.
        // e.g. if type_t can be converted to the type of m_size then select the first
        // bit to compile (that's what if constexpr is for)
        if constexpr (std::is_convertible_v<type_t,decltype(m_size)>)
        {
            m_size = static_cast<int>(value);
        }
        else
        // if a std::string can be constructed from type_t
        if constexpr (std::is_constructible_v<std::string, type_t>)
        {
            m_string = value;
            m_size = m_string.size();
        }
        else
        // give a compile time error (not a runtime one)
        {
            static_assert(false, "unsupported type for type_t");
        }
    }

    std::size_t size() const
    {
        return m_size;
    }

private:
    std::size_t m_size;
    std::string m_string;
};

//-------------------------------------------------------------------------------------------------

int main()
{
    my_class_t c1{ 42 };
    my_class_t c2{ "Hello world!" };

    std::cout << c1.size() << "\n";
    std::cout << c2.size() << "\n";

    my_class_template_constructor_t ct1{ 42 };
    my_class_template_constructor_t ct2{ "Happy new year!" };

    std::cout << ct1.size() << "\n";
    std::cout << ct2.size() << "\n";

    return 0;
}

The issue is not using a single parameter, but that you need later to find out the type of data of the parameter.问题不在于使用单个参数,而是您需要稍后找出参数的数据类型。

A commonly used trick it's to use either a generic Pointer, or a generic object class reference or Pointer.一个常用的技巧是使用通用指针或通用 object class 参考或指针。

MyClass::MyClass ( void* P );
MyClass::MyClass ( void& SomeBaseClass );

Since You are working for more simple data, You may want to try an OO approach like nesting the values in objects, and later, checking the type of the data:由于您正在处理更简单的数据,您可能想尝试一种 OO 方法,例如将值嵌套在对象中,然后检查数据的类型:

class BaseClass
{
  // ...
} ;

class IntegerClass: BaseClass
{
  int Value;
} ;

class StringClass: BaseClass
{
  String Value;
} ;

And your class can receive a "BaseClass" object reference:您的 class 可以收到“BaseClass” object 参考:

class MyClass
{
  private int MyInt;
  private String MyString;
  
  MyClass ( BaseClass& P ) 
  {
     if ( P is IntegerClass )
     {
       // 
     }
     else if ( P is StringClass )
     {
       //
     }
  }
} ;

int main (...)
{
  IntegerClass *i = new IntegerClass(5);
  StringClass *s = new StringClass ("Hello");
  
  MyClass *O1 = new MyClass(i);
  MyClass *O2 = new MyClass(s);
  
  // Display values of O1 and O2 here
  
  free O2;
  free O1;
   
  free s;
  free i;
  
  return 0;
}

Just my two bitcoins...就我的两个比特币...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM