为什么我对象刚刚一初始化就自动销毁了呢? (c++里面的类)

云松 发布于 2012/06/28 12:12
阅读 539
收藏 0

我做了一个类 socketaction,类里面的的构造函数使用了类本身的静态成员函数,当我在使用这个类实例化一个对象的时候

SocketAction* UDPSocket=new SocketAction();

我发现老是不能正常的初始化,于是我就用gdb跟踪了一下构造函数。

我step到构造函数的最后一句的时候就出现了我不能理解的情况。它竟然执行完构造函数之后直接跳进析构函数里面去了。我百思不得其解,我在想是不是因为我的构造函数里面调用了静态成员函数的原因?我把这个类的代码贴上来把。 

/*
 * MSocketAction.h
 *
 *  Created on: 2012-6-20
 *      Author: cloud
 */

#ifndef MSOCKETACTION_H_
#define MSOCKETACTION_H_
#include  "type.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <iostream>
using namespace std;

class SocketAction {

public:
	//Fun
	SocketAction();
	SocketAction(int fd, struct sockaddr_in *Client);
	static struct sockaddr_in* GetAClientAddr(const char* IPNum);
	int GetCurSocket();
	virtual ~SocketAction();
	void SetThePORT(unsigned short int port);
	static bool CreatSocket(int &fd);
	bool Action_bind();
	void InitAddr(struct sockaddr_in &server);
	bool Action_sendto(const char* buf);

	//recv
	bool Action_RecvFrom(char* buf);
	void Action_GetRecvFromInfo(char *Buf, sockaddr_in &Addr,
			unsigned int& RecvLen);
	void Action_PrintRecvF();
private:
	//VAR
	struct sockaddr_in Server;
	struct sockaddr Client;
	unsigned short int Port;
	int c_fd;
	unsigned int recv_len;
};

#endif /* MSOCKETACTION_H_ */

上面这个是头文件

/*
 * MSocketAction.cpp
 *
 *  Created on: 2012-6-20
 *      Author: cloud
 */

#include "MSocketAction.h"

SocketAction::SocketAction() {
	// TODO Auto-generated constructor stub
	int fd;
	SocketAction::CreatSocket(fd);
	SocketAction(fd, SocketAction::GetAClientAddr("127.0.0.1"));
}
SocketAction::SocketAction(int fd, struct sockaddr_in *Client) {
	this->c_fd = fd;
	this->Port = 8888;
	this->InitAddr(this->Server);
	this->Client = *((sockaddr*) Client);
	this->Action_bind();
	this->recv_len = 0;
}

SocketAction::~SocketAction() {
	// TODO Auto-generated destructor stub
	//	close(this->c_fd);
}
struct sockaddr_in* SocketAction::GetAClientAddr(const char* IPNum) {
	struct sockaddr_in* TempAddr = new sockaddr_in;
	TempAddr->sin_family = AF_INET;
	TempAddr->sin_port = 8888;
	TempAddr->sin_addr.s_addr = inet_addr(IPNum);
	return TempAddr;
}

int SocketAction::GetCurSocket() {
	return this->c_fd;
}
bool SocketAction::Action_bind() {
	if (bind(this->c_fd, (struct sockaddr*) &this->Server, sizeof(this->Server))
			== -1) {
		perror("fail to bind");
		return false;
	}
	return true;
}
void SocketAction::SetThePORT(unsigned short int port) { //
	this->Server.sin_port = port;
	struct sockaddr_in* Temp = (struct sockaddr_in*) (&this->Client);
	Temp->sin_port = port;
	this->Client = *(sockaddr*) Temp;
}
void SocketAction::InitAddr(struct sockaddr_in &server) {
	bzero(&server, sizeof(server));
	server.sin_family = AF_INET;
	server.sin_port = this->Port;
	server.sin_addr.s_addr = INADDR_ANY;
//	this->Server=server;
}
bool SocketAction::CreatSocket(int &fd) {
	fd = socket(AF_INET, SOCK_DGRAM, 0);
	if (fd == -1) {
		perror("had some err for create socket");
		exit(1);
	}
	return true;
}
bool SocketAction::Action_sendto(const char* buf) {
	int BufLen = strlen(buf) + 1;
	int len = sendto(this->c_fd, buf, BufLen, 0,
			(struct sockaddr*) &(this->Client), sizeof(this->Client));
	if (len == -1) {
		perror("send failed! ");
		return false;
	}
	return true;
}
bool SocketAction::Action_RecvFrom(char* buf) {
	memset(buf, 0, sizeof(buf));
	while (1) {
		if (0
				< recvfrom(this->c_fd, buf, CHAR_LEN_MAX, 0, &this->Client,
						&(this->recv_len))) {
			break;
		}
	}
	return true;
}

void SocketAction::Action_GetRecvFromInfo(char *Buf, sockaddr_in &Addr,
		unsigned int& RecvLen) {
	this->Action_RecvFrom(Buf);
	Addr = *(struct sockaddr_in*) (&this->Client);
	RecvLen = this->recv_len;
	return;
}
void SocketAction::Action_PrintRecvF() { //demo     !!!now !you can't use this
	char * TempBuf;
	this->Action_RecvFrom(TempBuf);
	cout << "what you Recved is from :" << this->Client.sa_data << "\n" << endl;
	while (1) {
		char* buf;
		this->Action_RecvFrom(buf);
		cout << buf << "\n" << endl;
	}
}

这个是cpp文件。

请指教下我啊,这到底是怎么样一回事啊。

加载中
0
Jooooooker
Jooooooker

在无参构造函数里面生成了一个该类型临时变量

SocketAction(fd, SocketAction::GetAClientAddr("127.0.0.1"));

然后退出作用域 进入这个临时变量的析构函数

应该是这样的

Jooooooker
Jooooooker
一个一个附值吧 不太理解你的this指针接受过来什么意思。。。
云松
云松
:-) ,谢谢你的回答。按照您说的,我是不是需要用this指针把有参数的构造函数接受过来
0
陈舵主
陈舵主

你的这个类不是基本,不作为抽象类,为何要弄成虚析构函数呢?virtual ~SocketAction();这样多了一个虚函数表,多占空间啊,,,

SocketAction(fd, SocketAction::GetAClientAddr("127.0.0.1"));

为什么要把SocketAction::GetAClientAddr("127.0.0.1")作为参数啊?你能把GetAClientAddr()这个函数调用写在函数里吗。。

 

云松
云松
呵呵,是这个构造函数调用构造函数的原因,我在contos上面,使用g++ 编译,没有报错。谢谢你的帮助。
陈舵主
陈舵主
回复 @zhuyunsong : 构造函数里不能在调构造函数了,至少我这里没编译过去,不知道你怎么编译过去的。。。
云松
云松
嗯? 对效率有影响还是有什么副作用吗?
陈舵主
陈舵主
回复 @zhuyunsong : 我把GetAClientAddr()作为参数,因为这个函数是直接返回了我需要的地址结构。...我知道,但你最好在函数里面调用,不要直接把函数的调用写在参数里
云松
云松
呵呵,谢谢你的指导,虚函数我没有考虑到,用eclipse 建一个类的时候析构函数就自动变成虚函数了,我当时没有多想,多亏你提醒!至于我把GetAClientAddr()作为参数,因为这个函数是直接返回了我需要的地址结构。所以就想省略一些步骤了。
0
mental
mental
是不是   CreatSocket 里面调用失败执行了exit(1) ; 试下把它改为 return false ; 
云松
云松
呵呵,感谢你的帮助,原因如1楼所说,我在构造函数里面调用了构造函数造成了作用域过后自动析构。
mental
mental
回复 @zhuyunsong : 清除工程 , 重新编译 , 有时我也会遇到这么诡异的问题,通常幸运的话重新编译就好了
云松
云松
呵呵。谢谢你的回答。我用gdb跟踪了的。每个step 我都看打印变量值出来了的。CreateSocket这个函数基本上都是正常的,至少我每次打印变量的时候都是正常的,我的跟踪过程中也没有出现过退出的情况。
返回顶部
顶部