c++ 中的实例化

发布于 2024-10-24 00:34:02 字数 1890 浏览 1 评论 0原文

首先,我想通知您,我已经明确搜索了以下问题的答案,但我是 C++ 的新手。

我刚刚摆脱了 C# 和 Java 的奢侈生活,现在正在尝试了解有关 c++ 的一两件事

。问题是关于实例化的。

我使用 code::block 作为我选择的 IDE。

(我实际上非常熟悉并且已经编写了几个应用程序),即

目前我只是在玩 C# 中的两个类

包含 main 和 Person 的类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


using Models.Person;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
           Person person = new Person();
           Console.WriteLine(person.getName());
        }
    }
}

以及 person 类:(

namespace ConsoleApplication1
{
   public class Person{
       private string name = "Bob";

       public string getName(){
           return name;
       }
   }
}

不要介意错误或正确的书面语法,它的只是为了模拟我想要实现的目标)

我想在 C++ 中实现相同的目标

,我已经查找过,并在一定程度上了解了标头,并掌握了一些语法。这就是我现在所拥有的。

main.cpp

#include <iostream>
using namespace std;

int main()
{
   Person person;
   cout << person->getName() << endl;
}

Person.h

#ifndef PERSON_H
#define PERSON_H

#include <string>

class Person
{
    public:
        Person();
        virtual ~Person();
        std::string getName();
    protected:
    private:
};

#endif // PERSON_H

player.cpp

#include "Person.h"
#include <string>

using std::string;

Person::Person()
{
    //ctor
}

Person::~Person()
{
}

string Person::getName()
{
    return name;
}

考虑到上面的代码,我有多个问题。

我从来没有找到一个好的来源来告诉我是否应该使用 Person person;Person person = new Person(); 实例

化,两者中哪一个是我的我应该使用吗?

我非常想知道的另一个问题是,我是在头文件中还是在类文件中定义类成员?

目前我收到以下错误:

“person”未在范围内声明,应为“;”人前

我不一定要求您解决我的错误,我会在收到我的问题的答案后进行解决。

First of all, I would like to notify you, I have definetly searched for answers about my following question, but im a complete newbie to C++.

I am coming from the luxurious life of C# and Java, now trying to pick up a thing or two about c++

The question is about instantiation.

I use code::block as my IDE of choice.

Currently I am just playing around with what in C# (which I'm actually quite familiar with and have written several applications in) is

2 classes

the class containing main and Person

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


using Models.Person;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
           Person person = new Person();
           Console.WriteLine(person.getName());
        }
    }
}

and the person class:

namespace ConsoleApplication1
{
   public class Person{
       private string name = "Bob";

       public string getName(){
           return name;
       }
   }
}

(dont mind bad or right written syntax, its just to simulate what i want to achieve)

I want to achieve the same in C++

I have looked up, and learned about headers to some extent, and picked up a bit of the syntax. This is what I have right now.

main.cpp

#include <iostream>
using namespace std;

int main()
{
   Person person;
   cout << person->getName() << endl;
}

Person.h

#ifndef PERSON_H
#define PERSON_H

#include <string>

class Person
{
    public:
        Person();
        virtual ~Person();
        std::string getName();
    protected:
    private:
};

#endif // PERSON_H

player.cpp

#include "Person.h"
#include <string>

using std::string;

Person::Person()
{
    //ctor
}

Person::~Person()
{
}

string Person::getName()
{
    return name;
}

Considering the above code, I have multiple questions.

I never found a good source that showed me whether I should instantiate using Person person; or Person person = new Person();

Which one of the two is the one I'm supposed to use?

And another question I'm dying for is, do I define class members in the header file or in the class file?

Currently I'm recieving the following errors:

'person' was not declared in scope and expected ';' before person

I'm not nescesarily asking you to resolve my errors, I'll manage that upon recieving answers on my questions.

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

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

发布评论

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

评论(8

云裳 2024-10-31 00:34:02

正如 larsmans 所说, Person personPerson *person = new Person() 会导致新的 Person 实例在堆栈/堆中分配分别。

这对您意味着什么(这是“我应该使用哪个?”问题的答案)是,在第一种情况下,对象的内存是自动管理的(这是好消息)。坏消息是对象的生命周期也是自动管理的,并且您无法控制它。一旦 person 变量超出范围,该对象就会被销毁。时期。

在第二种情况(new)中,对象的生命周期由您管理(它将一直存在,直到您删除 person)。这里的坏消息是内存也由您管理:如果您不执行delete person,分配给该对象的内存将会泄漏。如果您不再在范围内的任何地方引用 person ,那不会有任何区别。

因此,如果生命周期对您来说足够长,请不要使用指针。否则,你将不得不这样做。

对于类成员:

  • 必须在头文件中声明;如果您不声明它们并尝试使用它们,您将收到编译器错误。
  • 它们可以选择在头文件中定义;如果没有,你可以在.cpp文件中定义它们;如果您没有在任何地方定义它们并尝试使用它们,您将收到链接器错误。

一般来说,定义应该放在 .cpp 文件中,但如果您在标头中定义非常短的方法也没关系。

附录

当然,在这个简短的回答中,还有很多细节我没有提及。以下是您可能需要研究的一些重要问题:

  • 使用 new/delete 来管理内存,除了内存泄漏之外,还会产生许多其他问题; 悬空指针(指向已被释放的内存,因此不能再使用——这本质上是内存泄漏的“反向”错误)可能是列表中的第二名。
  • 使用某种智能指针将有助于实现“C#语义”:每当指向某些内存的最后一个智能指针超出范围时,该内存将当场自动释放 > (如果它指向一个对象,此时析构函数将运行;这称为确定性销毁,C# 没有它,它必须尝试使用​​ IDisposable)。您可以在 C++0x 和 Boost 中使用非常好的、成熟的智能指针。
  • 在 C++ 中,所有类型的工作方式都类似于 C# 值类型。如果 a 占用 2MB 内存,而您执行 b = a,则编译器只需使用 a 的副本填充全新的 2MB 内存code> (并且可能需要做很多额外的工作来实现这一点)。如果这不是您的意图,您需要存储一个指向 a 的指针或引用

As larsmans said, Person person and Person *person = new Person() are result in the new Person instance being allocated in the stack/heap respectively.

What this means for you (and this is the answer to the "which should I use?" question) is that in the first case, the memory for the object is managed automatically (that's the good news). The bad news is that the lifetime of the object is also managed automatically, and you don't have any control over it. As soon as the person variable goes out of scope, the object is destroyed. Period.

In the second case (new), the object's lifetime is managed by you (it will exist until you do delete person). The bad news here is that the memory is also managed by you: if you don't ever do delete person, the memory allocated to that object will leak. It won't make any difference if you have no reference to person anywhere in scope anymore.

So if the lifetime is long enough for you, don't use a pointer. Otherwise, you will have to.

For class members:

  • They have to be declared in the header file; if you don't declare them and try to use them, you will get a compiler error.
  • They may optionally be defined in the header file; if not, you can define them in the .cpp file; if you don't define them anywhere and try to use them, you will get a linker error.

Generally definitions should go to the .cpp file, but it's OK if you define really short methods in the header.

Addendum

Of course there are plenty of details I didn't touch upon in this short answer. Here's a few important ones you might want to look into:

  • Using new/delete to manage memory can also give birth to lots of other problems apart from memory leaks; dangling pointers (which point to memory that has been released, and therefore cannot be used anymore -- this is essentially the "reverse" error than a memory leak) is probably #2 on the list.
  • Using some kind of smart pointer will help in achieving "C# semantics": whenever the last smart pointer to some memory goes out of scope, the memory will be released automatically on the spot (if it points to an object the destructor will run at this time; this is called deterministic destruction, C# does not have it and it has to try to emulate it with IDisposable). There are very good and mature smart pointers you can use in C++0x and Boost.
  • In C++, all types work like C# value types. If a takes up 2MB of memory and you do b = a, you just had the compiler populate a brand new 2MB of memory with a copy of a (and probably do a lot of extra work to achieve that). If that is not your intention, you need to store a pointer or a reference to a instead.
蘑菇王子 2024-10-31 00:34:02
  1. Person person 将在堆栈上构造一个对象。 Person *person = new Person 将在空闲存储的内存中构造它(堆;注意 * 因为您需要一个指针)。这与 C# 不同,在 C# 中,您可以在 structclass 之间进行选择来获取堆栈或堆分配。在 C++ 中,这些关键字具有不同的含义。如果您选择在堆上分配,则稍后必须手动删除该对象。
  2. 实现小型的、性能关键的方法,这些方法不会在标头中发生更改。将其他所有内容放入实施文件中。

不要将 using 指令放在头文件的顶层。)

  1. Person person will construct an object on the stack. Person *person = new Person will construct it in memory on the free store (heap; note the * because you need a pointer). This differs from C#, where you'd choose between struct and class to get either stack or heap allocation. In C++, these keywords have a different meaning. If you choose to allocate on the heap, then you must later delete the object manually.
  2. Implement small, performance-critical methods that are not subject to change in the header. Put everything else in the implementation file.

(Please don't put a using directive at top-level in a header file.)

浅听莫相离 2024-10-31 00:34:02

与 C# 代码等效的内容如下:

#include <iostream>
#include <string>

class Person
{
   std::string name;
   public:
     Person() : name("Bob"){}
     std::string getName() { return name; }   
};

int main()
{
   //automatic variable; doesn't need new!
   Person person;
   std::cout << person.getName() << std::endl;

   //pointer ; need to use new
   Person *pPerson = new Person(); //it allocates memory!
   std::cout << pPerson->getName() << std::endl;
   delete pPerson; //it deallocates the memory!
}

输出:

Bob
Bob

请参阅在线演示:http://ideone.com/cM0uU

The equivalent of your C# code would be this:

#include <iostream>
#include <string>

class Person
{
   std::string name;
   public:
     Person() : name("Bob"){}
     std::string getName() { return name; }   
};

int main()
{
   //automatic variable; doesn't need new!
   Person person;
   std::cout << person.getName() << std::endl;

   //pointer ; need to use new
   Person *pPerson = new Person(); //it allocates memory!
   std::cout << pPerson->getName() << std::endl;
   delete pPerson; //it deallocates the memory!
}

Output:

Bob
Bob

See the online demo : http://ideone.com/cM0uU

娇柔作态 2024-10-31 00:34:02

关于 Person 的主要区别是你是否想要价值
语义或引用语义——对于实体对象,引用
语义是必要的(因为它们保留身份),但是对于
对于大多数其他人来说,值语义是更可取的。在你的例子中,
人们可以很容易地使用值语义,但在
更现实的情况,这取决于班级的角色
在应用程序中。

不管怎样,如果你定义了值语义,你就不会(几乎)
从不)动态分配实例。您将它们定义为本地的
变量,根据需要复制它们,然后让编译器获取
照顾其余的。您还确保副本、作业和
析构函数做你想做的事——在现代 C++ 中,这通常是
这种情况,因为您的应用程序级别对象将基于
具有复制构造函数、赋值和
破坏做正确的事,但这在过去并不是这样
情况确实如此,但今天情况并非总是如此。如果你想
实体语义,你必须决定实体的生命周期
实体应该是。 (我会说就像你在其他
语言,但许多 Java 和 C# 程序员忘记了这一点。和
常常侥幸逃脱。你永远不会逃脱它的惩罚
C++。)实体对象通常使用 new 创建,并且必须
当他们的生命结束时就会被摧毁。

禁止实体的复制和转让也是一个好习惯
C++ 中的对象(除了可能提供克隆函数)。

关于第二点:完整的类定义必须
位于一个地方;你不能重新打开定义一次
你已经用最后一个大括号将其关闭了。这意味着
成员函数声明(但不是定义)和
成员数据必须存在于类定义中
头文件。最好是尽量少放
然而,头文件和函数的定义(
实现)通常属于源文件。

(所有这些规则都有例外,但它们是一个很好的
起点。)

The main distinction concerning Person is whether you want value
semantics or reference semantics---for entity objects, reference
semantics are necessary (since they preserve identity), but for
most others, value semantics are preferrable. In your example,
Person could easily be made to work with value semantics, but in
a more realistic case, it would depend on the role of the class
in the application.

Anyway, if you define value semantics, you do not (almost
never) allocate instances dynamically. You define them as local
variables, copying them as needed, and let the compiler take
care of the rest. You also make sure that copy, assignment and
the destructor do what you want---in modern C++, this is usually
the case, as your application level objects will be based on
lower level objects with copy constructors, assignment and
destruction which do the right thing, but this didn't used to be
the case, and it isn't always the case today. If you want
entity semantics, you have to decide what the lifetime of the
entity should be. (I'd say just as you would in other
languages, but many Java and C# programmers forget this. And
often get away with it. You won't get away with it, ever, in
C++.) Entity objects are normally created using new, and must
be destructed when their lifetime ends.

It's also good practice to ban copy and assignment of entity
objects (except maybe to provide a clone function) in C++.

Concerning the second point: the complete class definition must
be in a single place; you can't reopen the definition once
you've closed it with the last curly brace. This means that
member function declarations (but not the definitions) and
member data must be present in the class definition, in the
header file. It's best to put as little as possible in the
header file, however, and the definitions of the functions (the
implementation) normally belongs in the source file.

(There are exceptions to all of these rules, but they're a good
starting point.)

假情假意假温柔 2024-10-31 00:34:02

ma​​in.cpp 的开头,您还必须#include "Person.h"

In the beginning of main.cpp you must also #include "Person.h".

灯下孤影 2024-10-31 00:34:02

在java中,一切都是引用类型,因此必须使用new来实例化,它创建一个值类型并返回对其的引用。在c++中,基本类型是值类型,而类似于java的引用类型看起来像Person* person;当你进入c++时,你真的应该放弃你从java中学到的一切,并从基础开始,从高级到低级编程确实会非常令人困惑

In java, everything is a reference type, and so has to be instantiated using new, which creates a value type and returns a reference to it. In c++, the basic type is a value type, and a reference type similar to a java one looks like Person* person; You should really drop everything you know from java when going into c++ and start from the basics, it really can be very confusing to go from high to low level programming

茶底世界 2024-10-31 00:34:02

如果您来自 C#,此解释可能会有所帮助:

在 C++ 中,类型的声明/定义不会说明它是“值类型”还是“引用类型”。 “struct”和“class”之间的唯一区别是“class”中的成员默认是私有的。这是你如何使用它决定的。

当您声明一个 Person 时,您将其创建为“值类型”。
当您声明 Person* 时,您正在创建一个指向 Person 的指针(C# 中的引用类型),该指针通常使用 new 在堆上分配代码>. C++ 中的引用(即 Person&)类似于 C# 中的 ref Person

正如 James 在他的评论中指出的那样,获得一本好的 C++ 书籍是你最好的选择。

If you're coming from C#, this explaination might be helpful:

In C++ the declaration/definition of a type doesn't say whether it is a "value type" or a "reference type". The only difference between 'struct' and 'class' is that members are private by default in 'class'. It's how you use it that determines this.

When you declare a Person, you are creating it as a "value type".
When you declare a Person*, you are creating a pointer (a reference type in C#) to a Person which normally is allocated on the heap with new. References (i.e. Person&) in C++ are like ref Person in C#.

As James points out in his comment, getting a good C++ book is your best bet.

哎呦我呸! 2024-10-31 00:34:02

您收到的错误来自于未使用 #include "Player.h" (假设这就是您为包含 class Person 声明的头文件命名的名称,因为这就是您的#define PLAYER_H 建议)。之后,它会抱怨,因为您使用的是 person->getName() 而不是 person.getName()-> 与指针一起使用,您可能应该阅读更多相关内容。

至于定义类成员,如果我正确理解术语,您应该在头文件中声明它们。然后,它们通常在类文件的构造函数中隐式定义。

class MyClass {
  int myVar;  // Declare the variable
public:
  MyClass(int inVar);  // Declare the constructor function
};

然后在类文件中:

MyClass::MyClass(int inVar)  // Define the constructor function
: myVar(inVar)     // Define the variable
{
}

当然,您可以在头文件中同时执行这两项操作,有时这样做是合适的。

class MyClass {
  int myVar;  // Declare the variable
public:
  MyClass(int inVar) // Declare and define the constructor function
  : myVar(inVar)
  {}
};

The errors you're getting come from not using #include "Player.h" (assuming that's what you named the header file containing the declaration for the class Person since that's what your #define PLAYER_H suggests). After that, it'll complain because you're using person->getName() instead of person.getName(). The -> is used with pointers you should probably read up a bit more on this.

As for defining class members, if I understand the terminology correctly, you should declare them in your header file. They are then defined, often implicitly, in the constructor in your class file.

class MyClass {
  int myVar;  // Declare the variable
public:
  MyClass(int inVar);  // Declare the constructor function
};

And then in the class file:

MyClass::MyClass(int inVar)  // Define the constructor function
: myVar(inVar)     // Define the variable
{
}

Of course, you can do both in the header file and it's appropriate to do so sometimes.

class MyClass {
  int myVar;  // Declare the variable
public:
  MyClass(int inVar) // Declare and define the constructor function
  : myVar(inVar)
  {}
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文