Неоднозначный вызов оператора [] внутри вложенного класса

Я пытаюсь создать структуру данных, которая имеет векторные функции для изучения C ++. В настоящее время я застрял, пытаясь скомпилировать код, подобный этому:

template<typename T>
class TestClass {
public:
T* data;
TestClass(const T& t) {
data = new T{ t };
}
~TestClass(void) {}
TestClass(const TestClass&) {}

T& operator[](int k) { return *data; }
const T& operator[](int k) const { return *data; }
class NestedClass {
public:
NestedClass(void) {}
~NestedClass(void) {}
T& operator*(void) { return operator[](0); }
};

NestedClass newNestedClass(void) {
return new NestedClass();
}
};

Я получаю неоднозначный вызов перегруженной функции на моем operator* функция внутри моего вложенного класса. Хотя я думаю, что у меня возникла проблема (как компилятор узнает, если это его rhs / lhs), я не совсем уверен, как это исправить. Я хочу использовать operator[] Функция для этого.

Я ожидаю, что эти две строки будут печатать одно и то же:

TestClass<int> t(1);
auto n = t.newNestedClass();
cout << t[0] << endl;
cout << *n << endl;
return 0;

Любой совет?

1

Решение

operator[] что вы определили для вашего TestClass никоим образом не «унаследован» или как-то «встроен» в ваш вложенный класс.

Вы можете думать о вложенных классах C ++ как об обычных классах, которые живут в «вложенном пространстве имен»: TestClass::NestedClass в вашем примере кода.

Если вы хотите operator[] для вашего вложенного класса, вы должны определить один с нуля (как вы сделали для вашего TestClass).


РЕДАКТИРОВАТЬ 1: Возвращение классов (C ++ Is Не Джава)

Также обратите внимание, что C ++ не как например Java (с шаблоном выделения экземпляров классов с newи полагаться на сборщик мусора для автоматического сбора «мусора»).
Итак, код такой:

   NestedClass newNestedClass(void) {
return new NestedClass();
}

не должен даже компилироваться.

Если вы вернули NestedClass Экземпляр динамически распределяется с new, вы должны вернуть указатель к этому, например:

   // Note the "*" for the returned pointer
NestedClass* newNestedClass() {
return new NestedClass();
}

Но это скорее шаблон Java.

В C ++ вы можете просто захотеть вернуть экземпляр NestedClass без new динамическое распределение; это должно работать просто отлично:

   NestedClass newNestedClass() {
return NestedClass();
}

РЕДАКТИРОВАТЬ 2: Правильное управление ресурсами

Обратите внимание, что вы можете сделать T* data; член private для лучшей инкапсуляции и сокрытия информации. Вы предоставляете надлежащее общественности аксессоры (как operator[] перегрузки) для доступа к данным вашего класса: выставить функции-члены аксессора, не члены данных.

Кроме того, вы динамично выделено data в кучу, используя new, Вы должны релиз динамически выделяемая куча памяти, чтобы избежать памяти (и ресурса) утечки.
Хорошее место для этого — ваш класс деструктор, например.:

class TestClass {
private:
T* data;

public:
...

~TestClass() {
// Release resoruces dynamically allocated
delete data;
}
}

Обратите внимание, что этот код:

data = new T{t};

просто динамически выделяет один экземпляр T, инициализируя его значением t,

Соответствующий код очистки:

delete data;

Однако, если вы хотите динамически выделить массив Ts, синтаксис:

data = new T[elementCount];
// ... initialize data to some value...

и соответствующий синтаксис очистки:

delete[] data; // Note the []!!

Также обратите внимание, что если вы хотите вручную управлять ресурсами в своем классе, вы должны рассмотреть также определение конструктор копирования а также копия задания operator=() (см. так называемый Правило трех); и если вы хотите реализовать переместить семантику, Вы также должны рассмотреть возможность реализации переместить конструктор а также переместить назначение (в этом случае есть соответствующий «Правило 5»).

Но если вы полагаетесь на уже доступны RAII ресурсные менеджеры, лайк std::vectorВы не должны тратить время, энергию и охоту на насекомых, управляя ресурсами вручную: это все автоматически управляемый std::vector, или какой-либо класс контейнера вы выбираете (в этом случае у вас есть простой «Правило нуля» 🙂 То есть стандартный конструктор копирования, сгенерированный компилятором, оператор присваивания копии, конструктор перемещения, оператор присваивания перемещения и деструктор сделают трудную задачу.

Но, конечно, если это учебное упражнение, вы можете реализовать эти специальные функции-члены самостоятельно.

2

Другие решения


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector