C++:为什么强制转换为指针然后取消引用会起作用?

发布于 2024-12-06 15:39:40 字数 1780 浏览 5 评论 0原文

最近我一直在 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;
}

Recently I have been working on sockets in C++ and I have come across this:

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

While this does do what I want it to I am a little confused as to why I can't do this:

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

Since it becomes a pointer and then immediately is dereferenced shouldn't the second work as well as the first? I am still new to C++ and this is a little confusing to me. Any help would be greatly appreciated. Below is the code. All it does is takes the host name or IP and prints the IP to the screen.

#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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

诠释孤独 2024-12-13 15:39:40

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

另一方面,指针可以随意投射。然而,这样做可能非常危险。如果需要强制转换,请在执行此操作时使用 static_cast 或dynamic_cast,并可能检查强制转换是否成功。以这种更明确的方式进行强制转换的另一个风格优势是,它使强制转换对于浏览您代码的人来说更加明显。

Objects can only be cast as another class if a constructor exists which accepts an argument of the original type.

Pointers, on the other hand, can be cast willy nilly. However, it can be very dangerous to do so. If it is necessary to cast, use static_cast or dynamic_cast when doing so, and potentially check to see if the cast was successful. One additional stylistic advantage to casting in this more explicit fashion is it makes the cast more blatant to someone browsing your code.

南巷近海 2024-12-13 15:39:40

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

double q = 0.5;
int n;

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

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

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

您的示例可能是有效的,因为所讨论的两种类型都是具有相同初始成员的 POD 结构,并且您仅访问公共初始成员之一。 编辑。我检查过,server->h_addr 的类型为char *。这可能只是用作占位符,而指针实际上指向正确类型的结构。

A simpler example might help to explain the difference:

double q = 0.5;
int n;

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

The first version converts the value of q into a value of type int according to the rules of the language. Conversion is only possible for primitive types and for classes that define conversion operators/constructors.

The second version reinterprets the binary representation of q as an integer. In good cases (like in your example) this produces something useful, but in general this is undefined behaviour, as it is not allowed to access a variable of one type through a pointer to a different type.

Your example may be valid because the two types in question are both POD structs with the same initial members, and you are accessing only one of the common initial members. Edit. I checked, server->h_addr is of type char *. It's possible that this just serves as a placeholder and the pointer is in fact to a structure of the correct type.

泪冰清 2024-12-13 15:39:40

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

在第一个代码片段中,您本质上是使用指针转换来解决这种类型不兼容问题。

What the code is doing is trying to re-interpret serv_addr.sin_addr.s_addr as a type in_addr. However, this conversion is not compatible. Therefore, you get a compiler error in the second snippet if you try a direct cast.

In the first snippet, you're essentially using pointer casting to get around this type incompatibility.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文