2014-10-10 4 views
0

У меня возникли проблемы с наследованием/вызовом конструктора базового класса. Я основывал класс на примере Boost.Asio.Наследование конструктора C++ (вызов конструктора из производного класса)

Вот родительского класс:

#ifndef CLIENT_HPP 
#define CLIENT_HPP 

#include <iostream> 
#include <memory> 
#include <utility> 
#include <boost/asio.hpp> 
#include <boost/lexical_cast.hpp> 

using boost::asio::ip::tcp; 

class client : public std::enable_shared_from_this<client> { 

    public: 
     client(tcp::socket socket) : socket_(std::move(socket)) { 

     } 

     void start() { 
     } 

     tcp::socket socket_; 

}; 

#endif 

Вот ребенка класс:

#ifndef PENGUIN_HPP 
#define PENGUIN_HPP 

#include "Client.hpp" 

class penguin : public client { 

    public: 
     penguin() : client(socket_) { 

     } 

}; 

#endif 

Это, как я инициализация Пингвина класса

std::make_shared<penguin>(std::move(socket_))->start(); 

socket_ здесь tcp :: socket thingy.

Я C++ noob, поэтому любой справка была бы принята с благодарностью!

+1

Похоже, вы ищете [делегирующий конструктор] (http://stackoverflow.com/questions/13961037/delegate-constructor-c) – CoryKramer

+0

Я не храню его – Nyaa

+1

Похож на конструктор 'penguin' должен принять аргумент. –

ответ

3

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

Теперь возникает вопрос, как вы вызываете конструктор базового класса в конструкторе производного класса. Ответ находится в списке инициализации конструктора производного класса, как и вы.

Однако есть проблема с тем, как вы на самом деле идти об этом

penguin() : client(socket_) {} 

Здесь socket_ является членом базового класса, client (если не опечатка в вашем посте.). socket_ ссылается доclient объект был создан, поэтому он еще не существует. Это проблема рода куриных яиц. Для того, чтобы создать экземпляр client, вам нужно socket_, но для того, чтобы ссылаться на socket_, вам нужно создать экземпляр client, и ритм продолжается ...

Я не сжатое кусок советы я могу дать вам устраните эту проблему, потому что, к сожалению, нет простого решения. Настоящая проблема заключается в том, что ваш дизайн сломан. Он сломан из-за циклической зависимости, которую вы вводите между базовым классом и членами этого базового класса. Вам нужно пересмотреть свой дизайн.

0

Что вы пытаетесь сделать, может быть упрощена в этом примере:

class foo 
{ 
public: 
    foo(int x); 

protected: 
    int m_x; 
}; 

class bar : public foo 
{ 
public: 
    bar(); 
}; 

// in bar.cpp: 
bar::bar() 
    :foo(foo::x) 
{ 
} 

Очевидно, что это не имеет никакого смысла. Вы не можете инициализировать объект со своим собственным членом данных, который еще не существует. В вашем случае вы пытаетесь инициализировать client со своим собственным socket_. Сначала вам нужно построить сокет где-то еще. Когда вы объявляете экземпляр класса, он создается по порядку от своего базового типа к его самому производному типу (сначала выполняется клиентский конструктор, затем пингвин и т. Д.), И он разрушается в обратном порядке. Конструктор пингвинов не «переопределяет» клиентский конструктор.

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

Мне также интересно, какое ваше определение C++ noob и почему вы пытаетесь создать сетевое программирование с boost :: asio и семантикой перемещения, если вы еще не знаете основ классов и конструкторов. Может быть, вы должны начать меньше.

+0

«socket_» здесь относится к переменной элемента базового класса с тем же именем. –