19

问题是在我将变量初始化bkNULL. 我的猜测是我应该提前保留内存空间来分配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;
};
4

8 回答 8

26

您将 bk 分配给 NULL ,然后尝试访问它的成员。这与 Java 中的空指针相同,您所做的通常会引发 NullPointerException(感谢评论)。如果要创建指向结构的指针,则需要使用 operator 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 语言。这是一种多范式的瑞士军刀语言。

于 2013-09-26T18:10:02.330 回答
4

这就是你需要的:

Book CreateBook( unsigned int pageNum){

    Book bk = new _book();

    bk->pageNum = pageNum;

    return bk;
}

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

使用完后不要忘记在 bk 上调用 delete。

于 2013-09-26T18:08:01.927 回答
2

书.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;
};

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

如果您需要抽象类型的不透明度,那么您才应该处理指针。当您确实处理指针时,将它们隐藏在 a 后面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;
};
于 2013-09-26T18:26:00.687 回答
0

Book bk;

bk是一个指针

先给它分配内存

Book bk* = new _book();

然后做

bk->pageNum = pageNum;

也不要忘记使用释放内存

delete bk;

于 2013-09-26T18:08:19.873 回答
0

你为什么要进行类型定义?在某些情况下,出于某种原因,我猜这可能是一种很好的做法。

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

_书本;

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

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

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

而不仅仅是说

vec3 位置(0.0, 1.0, 5.0);

就像你在 C++ 中一样。

于 2013-09-26T18:14:07.823 回答
0
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;
}
于 2013-09-26T18:16:51.437 回答
0

但是如果您不想从堆中创建变量,则可以直接创建并返回这种方式

bk = _book{any_data_that_you_want_to_insert};
// ...
return bk;
于 2019-06-30T14:44:32.990 回答
-2

您的代码中有一些错误。

  1. 您需要#endif在头文件的末尾添加一个。
  2. struct您需要在,class和定义的末尾放置一个分号(在右union大括号之后)。
  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反正你不需要这个功能,但我还是把它留了。

于 2013-09-26T18:10:18.493 回答