Как реализовать класс, который имеет один из двух типов для аргумента

#c

#c

Вопрос:

если у меня есть класс c , подобный:

 class Student
{ 
    public: 

    string name;
    int assigned_number;      
};
  

и я хочу использовать либо name, либо number, но не оба для каждого экземпляра, есть ли способ сделать это Or типом, где требуется только один из них?

Комментарии:

1. Комментарии типа // Access specifier являются беспорядком. Единственные люди, которые выиграют от этого, — это те, кто в любом случае вряд ли поймет большую часть вашего кода.

2. Что именно вы называете «обязательным»? В нынешнем виде a Student имеет эти два подобъекта, и обойти это невозможно. Возможно, то, что вы ищете, или является так называемым вариантом, который в основном представляет собой способ, которым один объект может отображаться как разные объекты, например std::variant .

Ответ №1:

Если вы используете C 17 или выше, вы можете использовать std::variant from <variant> :

 #include <iostream>
#include <variant> // For 'std::variant'

class Student
{
public:
    std::variant<std::string, int> name_and_id;
};

int main() {
    Student stud; // Create an instance of student

    // Pass a string and print to the console...
    stud.name_and_id = "Hello world!";
    std::cout << std::get<std::string>(stud.name_and_id) << std::endl;

    // Pass an integer and print to the console...
    stud.name_and_id = 20;
    std::cout << std::get<int>(stud.name_and_id) << std::endl;
}
  

std::variant является новым дополнением к C 17 и предназначен для замены объединений из C и имеет исключения в случае ошибок…

Комментарии:

1. Я рад, что вы удалили этот плохой совет, снова получил мой голос. Можно использовать boost::variant версию до C 17 (с вашей стороны было хорошо обратиться к этому, чего бы это ни стоило). Или реализовать свой собственный вариант, варианты типов всегда были возможны.

Ответ №2:

Вы можете использовать union.

 #include <string>

class Student
{
    // Access specifier 
public:
    Student()
    {

    }
    // Data Members
    union
    {
        std::string name;
        int assigned_number;
    };
    ~Student()
    {

    }
};

int main()
{
    Student test;
    test.assigned_number = 10;
    test.name = "10";
    return 0;
}
  

Комментарии:

1. не могли бы вы привести пример того, как вы бы создали экземпляр?

2. Вы пробовали запускать это? Ваш код приводит к сбоям в двух системах, которые я тестировал.

3. в вашем коде есть UB, потому что у вас есть нетривиальный деструктор в объединении. Код неверен! !