c++ 질문입니다.

balgarac1의 이미지

class CPacketHeader
{
public:
	UB2 msg_type;
	CPacketHeader(UB2 msgType);
	virtual ~CPacketHeader();
 
	virtual void CShowPacket() = 0;
};
 
 
class CLoginAuthReqPacket : public CPacketHeader
{
public:
	CLoginAuthReqPacket(UB2 msgType, SCHAR * dbUser, SCHAR * pw, SCHAR * dbName, SCHAR * pName);
	~CLoginAuthReqPacket();
 
	void CShowPacket();
private:
 
	SCHAR db_user[33];
	SCHAR password[33];
	SCHAR program_name[33];
	SCHAR db_name[33];
 
};
 
class CLoginAuthResPacket : public CPacketHeader
{
public:
	CLoginAuthResPacket(UB2 msgType, UB2 rtnLen, SCHAR * rtnMsg);
	~CLoginAuthResPacket();
 
	void CShowPacket();
private:
 
	UB2 rtn_len;
	SCHAR rtn_msg[257];
 
};

상속 구조를 갖고 있습니다.

CPacketHeader::CPacketHeader(UB2 msgType)
{
	msg_type = msgType;
}
 
// 로그인 요청 생성자
CLoginAuthReqPacket::CLoginAuthReqPacket(UB2 msgType, SCHAR * dbUser, SCHAR * pw, SCHAR * dbName, SCHAR * pName) : CPacketHeader(msgType)
{
	strcpy((char *)db_user, (char *)dbUser);
	strcpy((char *)password, (char *)pw);
	strcpy((char *)db_name, (char *)dbName);
	strcpy((char *)program_name, (char *)pName);
}
 
// 로그인 응답 생성자
CLoginAuthResPacket::CLoginAuthResPacket(UB2 msgType, UB2 rtnLen, SCHAR * rtnMsg) : CPacketHeader(msgType)
{
	rtn_len = rtnLen;
	strcpy((char *)rtn_msg, (char *)rtnMsg);
}
 
void CLoginAuthReqPacket::CShowPacket()
{
	cout << "[LOGIN AUTH REQ PACKET]" << endl;
	cout << "[MSG TYPE] : " << msg_type << endl;
	cout << "[DB USER] : " << db_user << endl;
	cout << "[PASSWORD] : " << password << endl;
	cout << "[PROGRAM NAME] : " << program_name << endl;
	cout << "[DB NAME] : " << db_name << endl;
}
 
 
void CLoginAuthResPacket::CShowPacket()
{
	cout << "[LOGIN AUTH RES PACKET]" << endl;
	cout << "[MSG TYPE] : " << endl;
	cout << "[LOGIN RES MSG]" << endl;
	cout << rtn_msg << endl;
};

이렇게 짰는데 각 생성자마다 빨간줄 그어지면서 선언한 가상함수를 구현하지 않았다고 그러는데..

전 구현헀는데 왜 에러가 발생하는건가요??

twinwings의 이미지

상속받은 함수를 오버라이딩을 할때 명시적으로 virtual 혹은 최신 C++11에서는 override 예약어를 사용하세요
(override 예약어를 사용했을 시, 코딩상 실수로 함수 시그네춰를 안맞출 경우 컴파일 에러를 띄워줍니다.)

그리고 제 컴파일러로는 에러는 뱉지 않는군요(linux, g++).
(컴파일은 g++ -c -Wall -Wextra a.cpp 로 했네요. 경고 하나도 안떳습니다.)

혹시 VS 쓰시나요? 예전에 VS 쓸 때 빌드 잔버그 많던데

빌드 정리 하고 나서 빌드 새로 해보셨나요?

PS. typedef 등만 추가하고 컴파일 했습니다. 똑같지만..올려봅니다.

헤더

typedef unsigned short UB2;
typedef char           SCHAR;
 
class CPacketHeader
{
public:
	UB2 msg_type;
	CPacketHeader(UB2 msgType);
	virtual ~CPacketHeader();
 
	virtual void CShowPacket() = 0;
};
 
 
class CLoginAuthReqPacket : public CPacketHeader
{
public:
	CLoginAuthReqPacket(UB2 msgType, SCHAR * dbUser, SCHAR * pw, SCHAR * dbName, SCHAR * pName);
	~CLoginAuthReqPacket();
 
	void CShowPacket();
private:
 
	SCHAR db_user[33];
	SCHAR password[33];
	SCHAR program_name[33];
	SCHAR db_name[33];
 
};
 
class CLoginAuthResPacket : public CPacketHeader
{
public:
	CLoginAuthResPacket(UB2 msgType, UB2 rtnLen, SCHAR * rtnMsg);
	~CLoginAuthResPacket();
 
	void CShowPacket();
private:
 
	UB2 rtn_len;
	SCHAR rtn_msg[257];
 
};

구현

#include "a.hpp"
#include <cstring>
#include <iostream>
 
using std::cout;
using std::endl;
 
CPacketHeader::CPacketHeader(UB2 msgType)
{
	msg_type = msgType;
}
 
// 로그인 요청 생성자
CLoginAuthReqPacket::CLoginAuthReqPacket(UB2 msgType, SCHAR * dbUser, SCHAR * pw, SCHAR * dbName, SCHAR * pName) : CPacketHeader(msgType)
{
	strcpy((char *)db_user, (char *)dbUser);
	strcpy((char *)password, (char *)pw);
	strcpy((char *)db_name, (char *)dbName);
	strcpy((char *)program_name, (char *)pName);
}
 
// 로그인 응답 생성자
CLoginAuthResPacket::CLoginAuthResPacket(UB2 msgType, UB2 rtnLen, SCHAR * rtnMsg) : CPacketHeader(msgType)
{
	rtn_len = rtnLen;
	strcpy((char *)rtn_msg, (char *)rtnMsg);
}
 
void CLoginAuthReqPacket::CShowPacket()
{
	cout << "[LOGIN AUTH REQ PACKET]" << endl;
	cout << "[MSG TYPE] : " << msg_type << endl;
	cout << "[DB USER] : " << db_user << endl;
	cout << "[PASSWORD] : " << password << endl;
	cout << "[PROGRAM NAME] : " << program_name << endl;
	cout << "[DB NAME] : " << db_name << endl;
}
 
 
void CLoginAuthResPacket::CShowPacket()
{
	cout << "[LOGIN AUTH RES PACKET]" << endl;
	cout << "[MSG TYPE] : " << endl;
	cout << "[LOGIN RES MSG]" << endl;
	cout << rtn_msg << endl;
};
twinwings의 이미지

그리고 개인적으로 네트워크 패킷 설계할 때 저는 이렇게 설계했습니다.

typedef struct _pkt_hdr {
    int type;
} pkt_hdr;
 
typedef struct _pkt_type_a {
  pkt_hdr hdr;
} pkt_type_a;
 
typedef struct _pkt_type_b {
  pkt_hdr hdr;
} pkt_type_b;
 
typedef union _pkt {
  pkt_hdr     hdr;
  pkt_type_a  type_a;
  pkt_type_b  type_b;
 
  char padd[PADD_LEN];
} pkt;
 
/**
 * out_buf: 직렬화된 데이터
 */
void serialise_type_a(pkt_typa_a *in_type_a, void *out_buf, int in_len);

그리고 직렬화 하는 별도의 함수 구현 하구요.

당연히 구조체 그대로 통째로 보내지 않습니다.

(byte order, memory alignement, 동적할당 데이터들...당연한거죠 ^^)

balgarac1의 이미지

감사합니다. 답변 주신 것 깊이 생각해서 적용하겠습니다.

jick의 이미지

에러가 났다고 질문을 할 때에는 에러메시지를 보여주는 편이 대답을 얻을 확률이 높습니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.