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

时间:2013-09-26 18:04:44

标签: c++ struct

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

Book.h

#ifndef Book_H
#define Book_H

struct _book;
typedef _book* Book;

Book CreateBook(unsigned int pageNum);

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

8 个答案:

答案 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)

您的代码中存在一些错误。

  1. 您需要在头文件的末尾添加#endif
  2. 您需要在structclassunion定义的末尾添加分号(在结束括号后)。
  3. 在这么简单的用例中,你根本不应该使用指针。
  4. 示例:

    Book.h

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

    Book.cpp

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

    无论如何你都不需要CreateBook功能,但无论如何我都离开了它。