Изящное решение копировать, константа и неконстанта, методы считывания? [дубликат]

После импорта файла JS просто добавьте ...

импортировать Choices из 'choices.js';

декларировать var Choices: любой;

112
задан Keith Pinson 8 February 2013 в 17:18
поделиться

8 ответов

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());
    }
};
102
ответ дан 24 November 2019 в 02:53
поделиться

Как насчет:

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. В анонимном пространстве имен. С внутренней связью. И табличка с надписью «Остерегайтесь леопарда».

27
ответ дан 24 November 2019 в 02:53
поделиться

Вот хороший однопроходный алгоритм, который я только что придумал, с временной сложностью O (N) и пространственной сложностью O (M) для чтения M строк из N-строчного файла.

Предположим, M <= N.

  1. Пусть S будет набором выбранных линий. Инициализировать S первыми M строками файла. Если порядок конечного результата важен, перемешайте S сейчас.
  2. Прочтите в следующей строке l . На данный момент мы прочитали n = M + 1 полных строк. Таким образом, вероятность того, что мы хотим выбрать l в качестве одной из наших последних строк, равна M / n .
  3. Принять l с вероятностью M / п ; используйте ГСЧ, чтобы решить, принять или отклонить l .
  4. Если l было принято,
7
ответ дан 24 November 2019 в 02:53
поделиться

Почему бы просто не вытащить общий код в отдельную частную функцию, а затем два других вызвать это?

5
ответ дан 24 November 2019 в 02:53
поделиться

Попробуйте устранить геттеры путем рефакторинга кода. Используйте дружественные функции или классы, если что-то требуется лишь для очень небольшого числа других вещей.

Как правило, геттеры и сеттеры нарушают инкапсуляцию, потому что данные открыты миру. Использование friend предоставляет данные только избранным, поэтому обеспечивает лучшую инкапсуляцию.

Конечно, это не всегда возможно, поэтому вы можете застрять с геттерами. По крайней мере, большая часть или весь «нетривиальный фрагмент кода» должна находиться в одной или нескольких частных функциях, вызываемых обоими геттерами.

4
ответ дан 24 November 2019 в 02:53
поделиться

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++).

2
ответ дан 24 November 2019 в 02:53
поделиться

Понятие «константа» существует не просто так. Для меня это устанавливает очень важный договор, на основе которого пишутся дальнейшие инструкции программы. Но вы можете сделать что-то в следующих строках: -

  1. сделать член «изменяемым»
  2. заставить «геттеры» const
  3. вернуть неконстантную ссылку

С этим можно использовать константную ссылку на LHS, если вам нужно поддерживать константную функциональность, когда вы используете геттер вместе с неконстантным использованием (опасно). Но теперь ответственность за поддержание инвариантов классов лежит на программисте.

Как было сказано ранее в SO, отказ от константности изначально определенного константного объекта и его использование - это UB, поэтому я бы не стал использовать приведение типов. return a pointer to it via a non-const member function.

  • No member functions can return non-const references. Only const references are allowed form const member functions.
  • This allows some consistency in the overall codebase and the caller can clearly see which calls can modify the member variable.

    1
    ответ дан 24 November 2019 в 02:53
    поделиться

    Я смею предложить с помощью препроцессора:

    #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)
    };
    
    -1
    ответ дан 24 November 2019 в 02:53
    поделиться
    Другие вопросы по тегам:

    Похожие вопросы: