Могут ли унаследованные классы быть const? [Дубликат]

Обратите внимание, что если вам это нужно в ситуации развертывания, подумайте о том, чтобы использовать Java WebStart (с версией «ondisk», а не сетевой, возможно в Java 6u10 и более поздней версии), поскольку он позволяет вам указать различные аргументы JVM в кросс-платформенном способе.

В противном случае вам понадобится специальная пусковая установка операционной системы, которая задает нужные вам аргументы.

7
задан Martin Darterson 28 June 2016 в 21:34
поделиться

7 ответов

Используйте член данных или частный базовый класс вместо общедоступного базового класса.

Затем вы контролируете доступ к этому члену.

Вы можете сделать свойство Property абстрактным интерфейсом, если вам нужно полиморфное поведение.

0
ответ дан Cheers and hth. - Alf 17 August 2018 в 14:20
поделиться

Вы можете использовать класс шаблона и специализацию для константного типа:

    template<typename T> class base_property {
    protected:
      T value;
    };
    template<typename T> class property : public base_property<T> {
    public:
      const T& get()const { return value; }
      void set(const T& v){ value = v; }
    };

    template<typename T> class property<const T> : public base_property<T> {
    public:
      const T& get()const { return value; }
    };

    class ConstChild : public property<const int>{ };
0
ответ дан Jesús Rocha 17 August 2018 в 14:20
поделиться
  • 1
    Это в основном просто создание целого отдельного класса в первую очередь. Не совсем в духе того, что было задано! – Lightness Races in Orbit 3 March 2018 в 21:40
  • 2
    но он отвечает на второй вопрос: «Если нет, есть ли у вас какие-либо другие идеи о том, как решить эту проблему?» и может использовать базовый класс для обоих, содержащих данные – Jesús Rocha 3 March 2018 в 21:54
  • 3
    В таком случае зачем беспокоиться о шаблоне? Просто два разных класса. Вы все равно должны их переопределить. – Lightness Races in Orbit 3 March 2018 в 21:59
  • 4
    Хорошо, теперь это немного лучше, хотя и практически эквивалентно существующим ответам. – Lightness Races in Orbit 3 March 2018 в 22:00
  • 5
    потому что тип данных говорит, какая специализация будет использовать, и может использовать его с любым типом данных, и если он добавит дополнительный параметр шаблона, он может использовать его как класс друга для доступа к члену данных – Jesús Rocha 3 March 2018 в 22:12

У меня есть трюк, а не чистое решение.

class ConstChild : private Property
{
    operator const Property () { return *this; }
};

, затем

ConstChild cc;
cc.set(10); // ERROR
cc().get();
-1
ответ дан Marco Amagliani 17 August 2018 в 14:20
поделиться
  • 1
    Это неверно на многих уровнях, сначала оператор преобразования никогда не будет называться gcc warnies warning: conversion function converting 'ConstChild' to its base class 'Property' will never be used. Тогда ConstChild не предоставляет operator(), поэтому cc() недействителен. Предположительно cc.operator const Property().get() будет, и в этом случае operator const Property& будет иметь больше смысла. Даже тогда синтаксис уродлив. Единственное, что имеет смысл, это объявить using Property::get внутри ConstChild. – alfC 8 January 2018 в 03:21

У меня возникла необходимость в связанной проблеме, которая заключается в том, чтобы действительно контролировать / выделять изменяемый и const-доступ для некоторого класса. Я сделал это с помощью этой простой многоразовой обертки шаблона:

template <typename T>
class TAccessor : private T
{
public:
    const T&    Const() const { return *this; }
    T&          Mutable() { return *this; }
};

// Example of use:
template <typename T>
using MyVector = TAccessor<std::vector<T>>;


void main()
{
    MyVector<int> vector;

    vector.Mutable().push_back(10);

    int x = vector.Const()[1];
    ...
}
3
ответ дан Philippe 17 August 2018 в 14:20
поделиться

Если вы создаете функцию const члена set, вы получите то, что вам нужно.

class Property
{
    int get() const;
    void set(int a);
};

class ConstChild : public Property
{
    void set(int a) const {}
};

Единственное предостережение в том, что хитрый пользователь может обойти ваше намерение, используя:

ConstChild child;
child.set(10);    // Not OK by the compiler

Property& base = child;
base.set(10);    // OK by the compiler
0
ответ дан R Sahu 17 August 2018 в 14:20
поделиться
  • 1
    и что, если объявлено void set(int a) как virtual? – Mike 28 June 2016 в 21:43
  • 2
    Кроме того, в дополнение к тому, насколько тривиально работать, это только отвечает на вопрос, если OP не может называть A::set() & quot; на самом деле означало «может называть это, но ничего не происходит» ... что я сомневаюсь. Можно было бы подумать, что они действительно означают, что он не может быть вызван, т. Е. Он будет генерировать ошибку компиляции, как и любую попытку вызвать метод non const в виде реального объекта const, к которому они обратили аналогию. – underscore_d 28 June 2016 в 21:46
  • 3
    Когда экземпляр ConstChild сам const, я мог бы вызвать его метод set, который заставил бы его выглядеть так, будто он на самом деле что-то делает, а это не так. В идеале строка Property& base = child; вызовет ошибку компилятора, поскольку она пытается отбросить const. – Martin Darterson 28 June 2016 в 21:49
  • 4
    @MartinDarterson, я не думаю, что вы можете получить точное поведение, которое вы ищете, с тем, что поддерживает данный язык. – R Sahu 28 June 2016 в 21:51
  • 5
    @MartinDarterson ... но вы можете легко реализовать функционально то же самое, используя предложение Шейна, которое, кроме того, имеет преимущество остановки людей от повторения «предпочитают композицию над наследованием». вам навсегда ;-) – underscore_d 28 June 2016 в 21:53

Я хотел бы наследовать от класса с помощью спецификатора const

. Как бы вы ни хотели, это не имеет значения. Вы не можете. Это недопустимо C ++.

Можно ли каким-либо образом использовать ключевое слово const для наследования? "

No.

2
ответ дан Remy Lebeau 17 August 2018 в 14:20
поделиться
  • 1
    Любые мысли во 2-й половине, «Если нет, есть ли у вас какие-либо другие идеи о том, как решить эту проблему?» – underscore_d 28 June 2016 в 21:42

Внести изменчивость позже в ваше дерево наследования и получить соответствующий результат:

class Property
{
    int get() const;
};
class MutableProperty : public Property {
{
    void set(int a);
};

И затем:

class ConstChild : public Property { ... };
class MutableChild : public MutableProperty { ... };
5
ответ дан Thomas B Preusser 17 August 2018 в 14:20
поделиться
  • 1
    Я понимаю, что это решение самой проблемы, хотя я указал, что я бы предпочел не создавать отдельный класс ReadOnlyProperty, что и есть то, что есть, просто с разными именами. – Martin Darterson 28 June 2016 в 21:51
  • 2
    Грант - хотя ваше именование было бы действительно нежелательным, так как Property также был бы ReadOnlyProperty, хотя он не был бы прочитан. В конце концов, я боюсь, что вы действительно просите о новой языковой функции. И неразумно представить, что все модификаторы, разрешенные для регулярных членов, также идут с суперклассами. – Thomas B Preusser 29 June 2016 в 06:08
Другие вопросы по тегам:

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