После импорта файла JS просто добавьте ...
импортировать Choices из 'choices.js';
декларировать var Choices: любой;
I recall from one of the Effective C++ books that the way to do it is to implement the non-const version by casting away the const from the other function.
It's not particularly pretty, but it is safe. Since the member function calling it is non-const, the object itself is non-const, and casting away the const is allowed.
class Foo
{
public:
const int& get() const
{
//non-trivial work
return foo;
}
int& get()
{
return const_cast<int&>(const_cast<const Foo*>(this)->get());
}
};
Как насчет:
template<typename IN, typename OUT>
OUT BigChunk(IN self, int index) {
// big, non-trivial chunk of code...
return something;
}
struct FooBar {
Something &getSomething(int index) {
return BigChunk<FooBar*, Something&>(this,index);
}
const Something &getSomething(int index) const {
return BigChunk<const FooBar*, const Something&>(this,index);
}
};
Очевидно, что у вас все еще будет дублирование объектного кода, но не дублирование исходного кода. В отличие от подхода const_cast, компилятор проверит правильность вашей константы для обеих версий метода.
Вероятно, вам нужно объявить два интересных экземпляра BigChunk как друзей класса. Это хорошее использование друга, так как функции друга скрыты рядом с другом, поэтому нет риска неограниченного связывания (ох-э!). Но сейчас я не буду пытаться использовать синтаксис для этого. Не стесняйтесь добавлять.
Скорее всего, BigChunk нужно уважать себя, в этом случае приведенный выше порядок определения не будет работать очень хорошо, и для его устранения потребуются некоторые предварительные объявления.
Кроме того, чтобы избежать бессмысленного нахождения BigChunk в заголовке и решения создать экземпляр и назовите это, даже если это морально конфиденциально, вы можете переместить все это в файл cpp для FooBar. В анонимном пространстве имен. С внутренней связью. И табличка с надписью «Остерегайтесь леопарда».
Вот хороший однопроходный алгоритм, который я только что придумал, с временной сложностью O (N) и пространственной сложностью O (M) для чтения M строк из N-строчного файла.
Предположим, M <= N.
S
будет набором выбранных линий. Инициализировать S
первыми M
строками файла. Если порядок конечного результата важен, перемешайте S
сейчас. l
. На данный момент мы прочитали n = M + 1
полных строк. Таким образом, вероятность того, что мы хотим выбрать l
в качестве одной из наших последних строк, равна M / n
. l
с вероятностью M / п
; используйте ГСЧ, чтобы решить, принять или отклонить l
. l
было принято, Почему бы просто не вытащить общий код в отдельную частную функцию, а затем два других вызвать это?
Попробуйте устранить геттеры путем рефакторинга кода. Используйте дружественные функции или классы, если что-то требуется лишь для очень небольшого числа других вещей.
Как правило, геттеры и сеттеры нарушают инкапсуляцию, потому что данные открыты миру. Использование friend предоставляет данные только избранным, поэтому обеспечивает лучшую инкапсуляцию.
Конечно, это не всегда возможно, поэтому вы можете застрять с геттерами. По крайней мере, большая часть или весь «нетривиальный фрагмент кода» должна находиться в одной или нескольких частных функциях, вызываемых обоими геттерами.
The const
reference to the object makes sense (you're putting a restriction on read-only access to that object), but if you need to allow a non-const
reference, you might as well make the member public.
I believe this is a la Scott Meyers (Efficient C++).
Понятие «константа» существует не просто так. Для меня это устанавливает очень важный договор, на основе которого пишутся дальнейшие инструкции программы. Но вы можете сделать что-то в следующих строках: -
С этим можно использовать константную ссылку на LHS, если вам нужно поддерживать константную функциональность, когда вы используете геттер вместе с неконстантным использованием (опасно). Но теперь ответственность за поддержание инвариантов классов лежит на программисте.
Как было сказано ранее в SO, отказ от константности изначально определенного константного объекта и его использование - это UB, поэтому я бы не стал использовать приведение типов. return a pointer to it via a non-const member function.
This allows some consistency in the overall codebase and the caller can clearly see which calls can modify the member variable.
Я смею предложить с помощью препроцессора:
#define ConstFunc(type_and_name, params, body) \
const type_and_name params const body \
type_and_name params body
class Something
{
};
class Foobar {
private:
Something something;
public:
#define getSomethingParams \
( \
int index \
)
#define getSomethingBody \
{ \
return something; \
}
ConstFunc(Something & getSomething, getSomethingParams, getSomethingBody)
};