Как работает переменная в C / C ++?

Как работает переменная в C / C ++

Я имею в виду, что указатель хранит адрес из переменной, а затем вам нужно разыменовать его, чтобы получить доступ к объекту, на который он ссылается, поэтому я думаю, что переменная - это указатель, который автоматически разыменовывается при использовании ... ...

можно пометить объявление метода в интерфейсе как " new ", но имеет ли оно какой-либо "технический" смысл или это просто способ явно заявить, что объявление не может переопределить предыдущий?

Например:

interface II1
{
    new void F();
}

interface II2 : II1
{
    new void F();
}

действителен (компилятор C # 4.0 не жалуется), но, похоже, не отличается от:

interface II1
{
    void F();
}

interface II2 : II1
{
    void F();
}

Заранее спасибо за любую информацию.

РЕДАКТИРОВАТЬ: Знаете ли вы сценарий, в котором было бы полезно скрыться в интерфейсе?

РЕДАКТИРОВАТЬ: Согласно этой ссылке: Является ли метод сокрытия когда-либо хорошей идеей (спасибо Скотту), наиболее распространенным сценарием является эмуляция ковариантного возвращаемого типа.

13
задан Machavity 7 August 2017 в 12:25
поделиться

4 ответа

Второй пример выдает следующее предупреждение компилятора:

'II2.F ()' скрывает унаследованный член 'II1.F ()'. Используйте новое ключевое слово, если сокрытие было предназначено.

Я бы сказал, что разница в использовании ключевого слова new именно в этом: демонстрация намерения.

8
ответ дан 1 December 2019 в 22:37
поделиться

Я знаю одно хорошее применение для этого: у вас есть для этого, чтобы объявить COM-интерфейс, производный от другого COM-интерфейса. Об этом говорится в журнальной статье .

Фвив, автор полностью неверно определяет источник проблемы, это не имеет ничего общего с «налогом на наследство». COM просто использует способ, которым типичный компилятор C ++ реализует множественное наследование. Для каждого базового класса есть одна v-таблица, именно то, что нужно COM. CLR этого не делает, он не поддерживает MI, и существует только одна v-таблица. Методы интерфейса объединены в v-таблицу базового класса.

4
ответ дан 1 December 2019 в 22:37
поделиться

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

Из Спецификация языка C # 3.0

10.3.4 Новый модификатор В объявлении-члене-класса разрешается объявлять член с тем же именем или подписью, что и унаследованный член. Когда это происходит, считается, что член производного класса скрывает член базового класса. Скрытие унаследованного члена не считается ошибкой, но вызывает предупреждение компилятора. Чтобы подавить предупреждение, объявление члена производного класса может включать новый модификатор, чтобы указать, что производный член предназначен для скрытия базового члена. Эта тема обсуждается далее в §3.7.1.2. Если в объявление включен новый модификатор, который не скрывает унаследованный член, выдается предупреждение об этом. Это предупреждение подавляется удалением модификатора new.

1
ответ дан 1 December 2019 в 22:37
поделиться

Они очень разные. Используя «новый», вы создаете новую цепочку наследования. Это означает, что любые реализации II2 должны будут реализовать обе версии F () , и фактическая версия, которую вы в конечном итоге вызовете, будет зависеть от типа ссылки.

Примите во внимание следующие три реализации:

    class A1 : II1
    {
        public void F()
        {
            // realizes II1.F()
        }
    }

    class A2 : II2
    {
        void II1.F()
        {
            // realizes II1.F()
        }

        void II2.F()
        {
            // realizes II2.F()
        }
    }

    class A3 : II2
    {
        public void F()
        {
            // realizes II1.F()
        }

        void II2.F()
        {
            // realizes II2.F()
        }
    }

Если у вас есть ссылка на A2 , вы не сможете вызвать ни одну из версий F () без предварительного преобразования в II1 или II2 .

A2 a2 = new A2();
a2.F(); // invalid as both are explicitly implemented
((II1) a2).F(); // calls the II1 implementation
((II2) a2).F(); // calls the II2 implementation

Если у вас есть ссылка на A3 , вы сможете вызвать версию II1 напрямую, поскольку это неявная реализация:

A3 a3 = new A3();
a3.F(); // calls the II1 implementation
((II2) a3).F(); // calls the II2 implementation
6
ответ дан 1 December 2019 в 22:37
поделиться
Другие вопросы по тегам:

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