C ++:为什么将转换作为指针然后解除引用工作?

时间:2011-09-24 01:00:57

标签: c++ sockets pointers struct dereference

最近我一直在用C ++编写套接字,我遇到过这个问题:

*(struct in_addr*)&serv_addr.sin_addr.s_addr = *(struct in_addr *)server->h_addr;

虽然这确实做了我想要的事情,但我有点困惑为什么我不能这样做:

(struct in_addr)serv_addr.sin_addr.s_addr = *(struct in_addr *)server->h_addr;

既然它变成一个指针然后立即被解除引用不应该第二个工作以及第一个工作?我还是C ++的新手,这对我来说有点困惑。任何帮助将不胜感激。下面是代码。它只需要主机名或IP并将IP打印到屏幕上。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>


using namespace std;

int main(){

    int socketfd, portno, rwResult; 
    struct sockaddr_in serv_addr; 
    struct hostent* server;     
    char inputName[50];

    //The next block gets the host name and port number and stores them in variables
    cout<<"Enter host(Max Size 50): ";
    cin>>inputName;
    cout<<endl<<"Enter port number: ";
    cin>>portno;
    cout<<endl;

    server = gethostbyname(inputName);
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(portno);

    *(struct in_addr*)&serv_addr.sin_addr.s_addr = *(struct in_addr *)server->h_addr;
    //This is where I am confused
    //(struct in_addr)serv_addr.sin_addr.s_addr = *(struct in_addr *)server->h_addr;


    cout<< "Server: "<<inet_ntoa(*(struct in_addr *)server->h_addr_list[0])<<endl;

    cout<< "Server: "<<inet_ntoa(*(struct in_addr *)&serv_addr.sin_addr.s_addr)<<endl;
    //The two cout's tell me if the address was copied correctly to serv_addr I believe.



    return 0;
}

3 个答案:

答案 0 :(得分:4)

如果存在接受原始类型参数的构造函数,则对象只能转换为另一个类。

另一方面,指针可以毫无疑问地施放。但是,这样做可能非常危险。如果需要强制转换,请在执行此操作时使用static_cast或dynamic_cast,并可能检查强制转换是否成功。以这种更明确的方式进行投射的另一个风格优势是它使得演员对于浏览代码的人更加明显。

答案 1 :(得分:3)

代码正在尝试将serv_addr.sin_addr.s_addr重新解释为类型in_addr。但是,此转换不兼容。因此,如果您尝试直接转换,则会在第二个代码段中出现编译器错误。

在第一个片段中,您实际上是使用指针转换来解决此类型的不兼容问题。

答案 2 :(得分:3)

一个更简单的例子可能有助于解释差异:

double q = 0.5;
int n;

n = (int) q;    // #1
n = *(int*)(&q) // #2

第一个版本根据语言规则将q转换为int类型的值。转换仅适用于基本类型和定义转换运算符/构造函数的类。

第二个版本将q的二进制表示重新解释为整数。在好的情况下(比如你的例子),这会产生一些有用的东西,但一般来说这是未定义的行为,因为不允许通过指向不同类型的指针访问一种类型的变量。

您的示例可能有效,因为有问题的两种类型都是具有相同初始成员的POD结构,并且您只访问其中一个常见的初始成员。 编辑。我选中了server->h_addr,类型为char *。它可能只是一个占位符,指针实际上是一个正确类型的结构。