#c #c 11
#c #c 11
Вопрос:
Я хочу вернуть копию struct из функции открытого класса, и я определяю эту структуру внутри этого класса как закрытый член.
Возможно ли вернуть эту структуру для любого другого типа пользовательских данных?
Рассмотрим этот простой пример:
class Test {
private:
struct sTest {
int i = 1;
}_sTest;
public:
sTest GetStruct() {
return _sTest;
}
};
затем после того, как я создам объект этого класса:
Test cTest;
как я могу вызвать
cTest.GetStruct()
чтобы получить
_sTest
?
Комментарии:
1. Проблема в том, что пользователь, который вызывает GetStruct(), не имеет доступа к закрытым элементам, и он / она не знает реализацию структуры.
2.Как вы ожидаете, что вызов кода приведет к k теперь, что делать с
sTest
возвращенным byGetStruct
, если имяsTest
является закрытым? Технически вы могли бы сделать что-то вродеauto something = sTest.GetStruct();
, потому что только имяsTest
является закрытым (демонстрация здесь), но… почему вы хотите это сделать? ЕслиsTest
предполагается, что an имеет значение для вызывающего кода, сделайте его частью открытого интерфейса класса.3. если я сделаю STest общедоступным, он не будет инкапсулирован. Все, что я хочу сделать, это прочитать данные, которые хранятся в частной структуре внутри класса. Есть ли лучшие способы?
4. также у меня есть дочерние классы, производные от CTest , которые перегружают GetStruct() и имеют свои собственные реализации структуры STest, поэтому мне нужно сделать STest уникальным для каждого дочернего класса
5. Если вы возвращаете an
sTest
в общедоступной функции и ожидаете, что вызывающий код сможет работать непосредственно с ansTest
, вы уже ничего не «инкапсулируете», потому что эти детали реализации должны быть известны. Возможно, выяснить, какие конкретные данные, хранящиеся в ansTest
, должны быть доступны пользователям класса, и написать функции, которые их возвращают?
Ответ №1:
Вы можете использовать auto
для хранения объекта.
Ниже приведен пример кода. Посмотрите это здесь в действии:
#include <iostream>
using namespace std;
class Test {
private:
struct sTest {
int i = 1;
}_sTest;
public:
sTest GetStruct() {
return _sTest;
}
};
int main()
{
Test a;
auto obj = a.GetStruct();
cout<< obj.i <<"nDone!!!n";
return 0;
}
Вывод:
1
Done!!!
Примечание: это нормально и для других компиляторов. Проверьте здесь и другие компиляторы.
Комментарии:
1. спасибо, да, я уже разобрался с этим обходным путем, но я сомневался, безопасно ли это.
2. @hgrev Я проверил компиляторы, доступные на coliru.stacked-crooked.com и это кажется прекрасным. Ни один из компиляторов не жаловался.
Ответ №2:
На всякий случай, если вы не хотите объявлять свою структуру в своем классе:
// not necessarily a member function
auto GetStruct()
{
struct sTest {
int i = 1;
};
return sTest();
}
using test_t = decltype(GetStruct()); // you can make an alias for an anonymous struct.
auto test = GetStruct();
Комментарии:
1. спасибо, интересно!
Ответ №3:
Поскольку частный класс недоступен из теста класса снаружи, используйте ключевое auto
слово .
auto test = cTest.GetStruct();
Ответ №4:
Да, это совершенно безопасно. Это похоже на любой другой тип данных. С помощью auto вы просто указываете компилятору угадать, какой будет переменная.