Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Интерфейсы(с виртуальными и невиртуальными методами) #32

Open
Neargye opened this issue Mar 13, 2021 · 0 comments

Comments

@Neargye
Copy link
Member

Neargye commented Mar 13, 2021

Перенос предложения: голоса +1, -5
Автор идеи: Виталий Псевдокенко

Интерфейсы в общем нужны для избежания ошибок при написания самого тела класса(то есть как можно раньше, а не при передаче объекта как аргумента функции или вообще багов на рантайме в случае использование множественного наследования), а также для подсказок IDE и автогенерации кода. Виртуальные интерфейсы для избежания проблем с множественным наследованием. Невиртуальные интерфейсы наподобие концептов в с++20, а также как их дополнение.

1 Интерфейсы в целом.

1.1 Для объявления интерфейса используется контекстное слово “interface” вместе с ключевым словом “class”

class interface MyInterface{
    // *** 
};

1.2 Объявления реализации интерфейса осуществляется так же как и при наследовании класса от другого класса, только без указания модификатора доступа наследования.

class interface MyInterface: OtherInterface1, OtherInterface2{
    // *** 
};

1.3 При реализации интерфейса запрещается множественное наследование от классов(целесообразность этого пункта под вопросом)

1.4 Интерфейс может использоваться так же как и концепт (под капотом компилятор создаёт концепт без имени с проверкой std::is_base_of):

template<MyInterface T>
void func(T x);

1.5 Уточнения std::is_base_of для интерфейсов, и/или добавление отдельного библиотечного класса для такой проверки.

1.6 Методы с реализацией по умолчанию:

class interface MyInterface{
    // Метод без реализации
    void test();
    
    // Метод с реализацией по умолчанию вне тела класа или с реализацией компилятора(к 
    // примеру операторы сравнения начиная с c++20
    void test2() = default;

    // Метод с реализацией по умолчанию внутри класа
    void test3() = default {
        // ...
    }
};

1.7 Для всех модификаторов доступа разрешены пользовательские типы и статические члены.

1.8 Для модификатора доступа “protected” разрешены также методы с реализацией по умолчанию.

1.9 Для модификатора доступа “public” разрешены также методы с и без реализации.

1.10 Для модификатора доступа “private” разрешено все то же что и в обычном классе, а также приватный конструктор по умолчанию, который всегда вызывается только конструкторами реализующих классов или в интерфейсах, которые расширяют интерфейс.

1.11 Члены с модификатором “private” используются методами с реализацией по умолчанию.

1.12 Для переопределения метода при колизии используется ключевое слово “using”:

class interface MyInterfaceA{
    int test(int a, int b) = default{
       return a + b;
    }
};

class interface MyInterfaceB {
    int test(int a, int b) = default{
       return a + b;
    }
};

class interface MyInterfaceC: MyInterfaceA, MyInterfaceB {
    using int MyInterfaceB::test(int a, int b);
};

class MyClass: MyInterfaceA, MyInterfaceB {
    using int MyInterfaceA::test(int a, int b);
};

1.13 Модификатор доступа по умолчанию - “public” .

1.14 Определения виртуального или невиртульного метода:

class interface MyInterfaceA{
    void test1();
    virtual void test2();
};

class interface MyInterfaceB: MyInterfaceA{
    void test1() = default{
        // ...
    }

    virtual void test2();
};

class MyClassB: MyInterfaceB{

};

class interface MyInterfaceC: MyInterfaceB{
    virtual void test2() = default{
        // ...
    }
};

class MyClassC: MyInterfaceC{

};

int main(){
   MyInterfaceA * ptr; // ОШИБКА: у интерфейса есть нереализованые невиртуальные методы 
   MyInterfaceB * ptr; // ОК

   MyClassB obj; // ОШИБКА: у интерфейса есть нереализованые виртуальные методы
   MyClassC obj; // ОК

}

2 Невиртуальные методы интерфейса

2.1 Разрешается использования “override”, “final”, “= 0” для невиртуальных методов интерфейса для проверки в классе реализации метода:

class interface MyInterface{
    void test1();

    void test_final();};
class MyClass1{public:
    void test1() override { //...} // ОК
    void test2() override { //...} // ОШИБКА

    void test_final() final override { // ...}}
class MyClass2: public MyClass1{public:
    void test_final() override { // ...} // ОШИБКА
    void test_final() { // ...}          // ОК}
}

2.2 Специальная конструкция для определения типа класса, который реализуюет невиртуальный метод (определяется при каждой реализации, так как невиртуальный метод недоступен по ссылке или указателю интерфейса или класса, который не реализует метод); (используется как синтаксический сахар над CRTP, и в случае переопределения метода):

class interface MyInterface{

    auto test(); // auto - может содержать тип класса, который реализует интерфейс
}

class MyClass1: MyInterface{

     MyClass1 test() override{//...} //ОК

     int test() override{//...} //ОШИБКА 
}

class MyClass2: public MyClass1{

     MyClass2 test() override{//...} //ОК

}​
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant