问题是在我将bk
变量初始化为NULL
后立即出现"访问冲突,写入位置0x00000000" 错误消息。我的猜测是我应该提前预留内存空间来分配NULL
(像Book bk = new Book();
这样的东西),但到目前为止我还没弄清楚如何在C ++中做到这一点。
#ifndef Book_H
#define Book_H
struct _book;
typedef _book* Book;
Book CreateBook(unsigned int pageNum);
#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;
};
答案 0 :(得分:23)
您将bk分配给NULL,然后尝试访问其成员。这与Java中的空指针相同,而您正在做的事情通常会引发NullPointerException(感谢评论)。如果要创建指向结构的指针,则需要使用operator new:
bk = new _book;
// ...
return bk;
然后确保在完成后调用指针上的删除。
我建议不要在这里使用指针。与其他语言不同,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语言。这是一种多范式的瑞士军刀语言。
答案 1 :(得分:3)
这就是你需要的:
Book CreateBook( unsigned int pageNum){
Book bk = new _book();
bk->pageNum = pageNum;
return bk;
}
你的bk为null,当指针为空时你无法访问pageNum。
当你完成使用它时,不要忘记在bk上调用delete。
答案 2 :(得分:2)
<强> Book.h 强>
#ifndef Book_H
#define Book_H
// why not put the layout here?
struct Book
{
int pageNum;
};
Book CreateBook(unsigned int pageNum);
#endif
<强> Book.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
* Book.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;
};
答案 3 :(得分:0)
在
Book bk;
bk
是一个指针
首先为它分配内存
Book bk* = new _book();
然后再做
bk->pageNum = pageNum;
另外不要忘记使用
释放内存 delete bk;
答案 4 :(得分:0)
你为什么要做typedefing?在某些情况下,出于某种原因,我认为这是一种很好的做法。
如果你不知道,你也可以写:
_ book book;
现在book是静态分配在堆栈上而不是在堆中动态分配。当变量超出范围时,它会被自动销毁,就像int或double等......
如果你想避免为非常简单的事情分配内存的开销或工作,这有时很有用。对我来说,进入Java并且不得不说,这很奇怪,
vec3 position = new Vec3(0.0,1.0,5.0);
而不只是说
vec3位置(0.0,1.0,5.0);
就像在C ++中一样。答案 5 :(得分: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;
}
答案 6 :(得分:0)
但是如果您不想从堆中创建变量,则可以直接创建并以这种方式返回
bk = _book{any_data_that_you_want_to_insert};
// ...
return bk;
答案 7 :(得分:-2)
您的代码中存在一些错误。
#endif
。struct
,class
和union
定义的末尾添加分号(在结束括号后)。示例:
#ifndef BOOK_H
#define BOOK_H
struct Book
{
int pageNum;
};
Book CreateBook(int pageNum);
#endif
#include "Book.h"
Book CreateBook(int pageNum)
{
Book bk;
bk.pageNum = pageNum;
return bk;
}
无论如何你都不需要CreateBook
功能,但无论如何我都离开了它。