2017-01-24 3 views
0

Я использую MySQL-conntector ++, и я заинтересован некоторыми из поведения типов указателей, таких как:Сложное поведение вложенных указателей класса?

sql::Driver *driver__; 

или

sql::Connection *connection__; 

Очевидно ::Driver и ::Connection вложенные классы sql , когда я пытаюсь инициализировать любой из этих указателей в куче:

sql::Driver *driver__ {new sql::Driver()}; 

Ошибка:

error: invalid new-expression of abstract class type ‘sql::Driver’ 
    sql::Driver *driver__ {new sql::Driver()}; 

Как библиотеки реализуют этот тип поведения с вложенными классами и указателями на такие классы?

Я просмотрел исходный код mysql-connector ++ и, похоже, не могу определить соответствующий раздел.

N.B вышеуказанные ошибки были получены с использованием CMake с -std=c++14

+2

Я понятия не имею о mysql-connector ++, но кажется, что 'sql :: Driver' является абстрактным классом (имеет хотя бы одну чистую виртуальную функцию), поэтому вы не можете создавать экземпляры его. Это справедливо для классов в целом, независимо от их объема. –

+1

Очевидно, библиотека создает объекты производных классов и использует указатель upcast (который неявный) для хранения указателя в 'sql :: Driver *'. –

+3

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

ответ

3

How do libraries implement this type of behavior with nested classes and pointers to such classes?

Бетонные экземпляры абстрактных классов существуют только в качестве базового класса к югу от объекта. Способ сделать то наследование:

struct MyDriver : sql::Driver { 
    //TODO implement all pure virtual functions of sql::Driver 
} 

// imaginary implementation 
Driver* get_driver_instance() { 
    static MyDriver instance; 
    return &instance; 
} 

PS. Тот факт, что Driver является членом sql (namespace?), Незначителен для пользователя другим способом, за исключением того, как он влияет на поиск имени.

0

В самом деле, когда вы объявляете

sql::Driver *driver__; 
sql::Connection *connection__; 

вы объявляете ссылки на экземпляры, которые реализуют интерфейсы:

  • SQL-подключения драйвера
  • SQL-

Для того, чтобы стимулировать такие случаи, библиотека предоставляет вам фабрики таким образом

driver__ = get_driver_instance(); 
connection__ = driver->connect("tcp://127.0.0.1:3306", "root", "root"); 

После установки вы будете манипулировать только общими интерфейсами таких экземпляров.

Смежные вопросы