如何在C++中创建结构的实例

How to create an instance of a struct in C++?

本文关键字:结构 实例 创建 C++      更新时间:2023-10-16

问题是在我将bk变量初始化为NULL后立即出现"访问冲突写入位置0x00000000"错误消息。我的猜测是我应该提前预留内存空间来分配NULL(类似于 Book bk = new Book(); ),但直到现在我还无法弄清楚如何在C++中做到这一点。

书.h

#ifndef Book_H
#define Book_H
struct _book;
typedef _book* Book;
Book CreateBook(unsigned int pageNum);

书.cpp

#include "Book.h"
#include <iostream>
#ifndef Book_CPP
#define Book_CPP
using namespace std;
struct _book
{
    int pageNum;
};
Book CreateBook( unsigned int pageNum){
    Book bk = NULL; 
    bk->pageNum = pageNum;
    return bk;
};

您正在将 bk 分配给 NULL,然后尝试访问它的成员。这与 Java 中的空指针相同,您正在做的事情通常会引发 NullPointerException(感谢评论)。如果要创建指向结构的指针,则需要使用运算符 new:

bk = new _book;
// ...
return bk;

然后确保在完成操作后在指针上调用 delete。

不过,我建议不要在这里使用指针。与其他语言不同,C++允许您按值创建对象。它还允许引用和指针,但仅在绝对必要时使用指针。如果你只是想创建一个具有给定 pageNum 的 book 对象,你应该在使用它时创建一个构造函数:

struct _book {
    int pageNum;
    _book(int n) : pageNum(n) // Create an object of type _book.
    {
    }
};

然后你可以像

_book myBook(5); // myBook.pageNum == 5

如果你是C++新手,请给自己一本关于它的好书。它不仅仅是一种低级语言,也不仅仅是一种 OOP 语言。这是一种多范式的瑞士军刀语言。

这是你需要的:

Book CreateBook( unsigned int pageNum){
    Book bk = new _book();
    bk->pageNum = pageNum;
    return bk;
}

您的 bk 为空,当指针为空时,您无法访问 pageNum。

并且不要忘记在使用完后在bk上调用删除。

Book.h

#ifndef Book_H
#define Book_H
// why not put the layout here?    
struct Book
{
    int pageNum;
};
Book CreateBook(unsigned int pageNum);
#endif

书.cpp

#include "Book.h"
// no #define guards
// do not using namespace std;, it is a bad habit
Book CreateBook( unsigned int pageNum){
  Book bk;
  bk.pageNum = pageNum;
  return bk;
};

这是最简单的解决方案。 书籍是实际值,可以复制和移动等。

如果你需要抽象类型的不透明度,只有这样你才应该处理指针。 当你处理指针时,将它们隐藏在typedef后面是一个坏主意:指针意味着资源管理,所以你应该很明显你正在使用它们。

基于指针的版本:

#ifndef Book_H
#define Book_H
// why not put the layout here?    
struct Book;
Book* CreateBook(unsigned int pageNum);
#endif
*

书.cpp *

#include "Book.h"
// no #define guards
// do not using namespace std;, it is a bad habit
Book* CreateBook( unsigned int pageNum){
  Book* bk = new Book;
  bk->pageNum = pageNum;
  return bk;
};

但是,如果你正在创建东西,你可能应该创建智能指针:

#include <memory>
std::shared_ptr<Book> CreateBook( unsigned int pageNum){
  std::shared_ptr<Book> bk( new Book );
  bk->pageNum = pageNum;
  return bk;
};

in

Book bk;

bk是指针

首先为其分配内存

Book bk* = new _book();

然后做

bk->pageNum = pageNum;

另外不要忘记使用

delete bk;

你为什么要做打字? 我想在某些情况下,出于某种原因,这可能是很好的做法。

如果你不知道,你也可以只写:

_book书;

现在,book 是在堆栈上静态分配的,而不是在堆中动态分配的。 当变量超出范围时,它会自动销毁,就像 int 或 double 等一样......

如果您想避免为非常简单的事情分配内存的开销或工作,这有时很有用。 对我来说,进入Java并不得不说,

VEC3 位置 = 新的 Vec3(0.0, 1.0, 5.0);

而不是说

VEC3位置(0.0, 1.0, 5.0);

就像你在C++一样。

struct Book{
    int pageNum;    
};
Book* createBook(int pageNum){
    Book *result = new Book;
    result->pageNum = pageNum;
    return result;
}
int main(int argc, char** argv){
    Book book;
    book.pageNum = 0;
    return 0;
}

struct Book{
    int pageNum;    
    Book(int pageNum_ = 0)
    :pageNum(pageNum_){
    }
};
Book* createBook(int pageNum){
    return new Book(pageNum);
}
int main(int argc, char** argv){
    Book book(0);
    return 0;
}

但是如果你不想从堆创建一个变量,那么你可以直接创建并返回这种方式

bk = _book{any_data_that_you_want_to_insert};
// ...
return bk;

代码中存在一些错误。

  1. 您需要在头文件的末尾放置一个#endif
  2. 您需要在structclassunion定义的末尾放置一个分号(在右大括号之后)。
  3. 在如此简单的用例中,您根本不应该使用指针。

例:

书.h

#ifndef BOOK_H
#define BOOK_H
struct Book
{
    int pageNum;
};
Book CreateBook(int pageNum);
#endif

书.cpp

#include "Book.h"
Book CreateBook(int pageNum)
{
    Book bk;
    bk.pageNum = pageNum;
    return bk;
}

无论如何,您都不需要CreateBook功能,但我还是将其保留了。