指针和类之间的交互 我最近一直在学习C++背景下的java语言和其他高级语言。我在指针和对象方面遇到了一些问题,我还没有找到一个好的资源来准确地解释如何使用指针操作用自定义类创建的对象

指针和类之间的交互 我最近一直在学习C++背景下的java语言和其他高级语言。我在指针和对象方面遇到了一些问题,我还没有找到一个好的资源来准确地解释如何使用指针操作用自定义类创建的对象,c++,class,pointers,object,c++11,C++,Class,Pointers,Object,C++11,我写了一个简单的程序,试图缩小我的问题所在 这个类底部的最后两段代码是错误的,我敢打赌我在其他部分也做了一些错误的事情。感谢您的帮助 #include <iostream> #include <cstdlib> #include <string.h> using namespace std; class Point { public: float x; float y; public: Point(float x, fl

我写了一个简单的程序,试图缩小我的问题所在

这个类底部的最后两段代码是错误的,我敢打赌我在其他部分也做了一些错误的事情。感谢您的帮助

#include <iostream>
#include <cstdlib>
#include <string.h>

using namespace std;

class Point {
public: 
    float x;
    float y;    
public: 
    Point(float x, float y) {
        this->x=x;
        this->y=y;
    }
    Point() {
        x=0.0f;
        y=0.0f;
    }
    ~Point() {
        x=0.0f;
        y=0.0f;
    }
};

class Place {
public: 
    string name;
    Point location;
public: 
    //Constructor with arguements.
    Place(string nam, Point loc) {
        name = nam;
        location = loc;
    }
    //Default constructor.
    Place() {
        name = "Default";
        location = {0.0f,0.0f};
    }
    //Destructor. This object contains no pointers so nothing to delete.
    ~Place() {

    }
public: 
    void setName(string nam) {
        name = nam;
    }
    void setLocation(Point loc) {
        location = loc;
    }
};

class PointerToAPlace {
public: 
    Place *place;
public:
    PointerToAPlace(Place *pl) {
        *place = *pl;
    }
    ~PointerToAPlace() {
        delete place;
    }
};

int main(int argc, char** argv) {
    std::cout << "\n";
    std::cout << "Make some places and hope they don't segfault.\n";


    /*Object created with default constructor. Will be automatically deleted at the end of this scope.*/
    Place placeA;
    std::cout << "Place named " << placeA.name.c_str() << " is at " << placeA.location.x << "," << placeA.location.y << " and is lovely.\n";
    //Output: Place named Default is at 0,0 and is lovely.


    /*Object created with bracket constructor. Will be automatically deleted at the end of this scope.*/
    Place placeB = {"Lordran", Point{12.2f,99.3f}};
    std::cout << "Place named " << placeB.name.c_str() << " is at " << placeB.location.x << "," << placeB.location.y << " and is lovely.\n";
    //Output: Place named Lordran is at 12.2,99.3 and is lovely.


    /*Object created with new keyword. This is a pointer and must be explicitly deleted.*/
    Place *placeC = new Place("Drangleic", Point{-123.34f,69.69f});
    std::cout << "Place named " << placeC->name.c_str() << " is at " << placeC->location.x << "," << placeC->location.y << " and is lovely.\n";
    delete placeC;
    //Output: Place named Drangleic is at -123.34,69.69 and is lovely.


    /*Array of objects, created with default constructor and not assigned any values. Will be automatically deleted at the end of this scope.*/
    Place placeD[3];
    std::cout << "Here are some places named: ";
    for(int i=0;i<3;i++) {
        std::cout << placeD[i].name.c_str();
        std::cout << (i<2 ? ", " : ". ");
    }
    std::cout << "They are quite the places!\n";
    //Output: Here are some places named: Default, Default, Default. They are quite the places!    


    /*Array of objects, created with default constructor and then assigned values. Will be automatically deleted at the end of this scope.*/
    Place placeE[5];
    string namesA[5] = {"Boletaria", "Stonefang", "Latria", "Shrine of Storms", "Valley of Defilement"};
    for(int i=0;i<5;i++) {
        placeE[i].setName(namesA[i]);
        placeE[i].setLocation(Point{1.23f, 3.21f});
    }
    std::cout << "Here are some places named: ";
    for(int i=0;i<5;i++) {
        std::cout << placeE[i].name.c_str();
        std::cout << (i<4 ? ", " : ". ");
    }
    std::cout << "They are quite the places!\n";
    //Output: Here are some places named: Boletaria, Stonefang, Latria, Shrine of Storms, Valley of Defilement. They are quite the places!


    /*Trying to do a pointer to an array of objects.*/
    Place *placeF[7];
    string namesB[7] = {"Astora", "Carim", "Thoroughland", "Catarina", "Baulder", "Vinheim", "Zena"};
    for(int i=0;i<7;i++) {
        placeF[i]->setName(namesB[i]);
        placeF[i]->setLocation(Point{2.23f, 6.21f});
    }
    std::cout << "Here are some places named: ";
    for(int i=0;i<7;i++) {
        std::cout << placeF[i]->name.c_str();
        std::cout << (i<6 ? ", " : ". ");
    }
    std::cout << "They are quite the places!\n";
    //Output: SEGFAULT D:

    /*Trying to put a pointer to a place into an object, then delete it.*/
    Place *placeG = new Place("Anor Londo", Point{-12312.34f,33.69f});
    PointerToAPlace pnt = {placeG};
    std::cout << "Place named " << pnt.place->name.c_str() << " is at " << pnt.place->location.x << "," << pnt.place->location.y << " and is lovely.\n";
    //Output: SEGFAULT :(

    return 0;
}
#包括
#包括
#包括
使用名称空间std;
类点{
公众:
浮动x;
浮动y;
公众:
点(浮动x、浮动y){
这个->x=x;
这->y=y;
}
点(){
x=0.0f;
y=0.0f;
}
~Point(){
x=0.0f;
y=0.0f;
}
};
班级{
公众:
字符串名;
点定位;
公众:
//带参数的构造函数。
地点(串南,点位){
姓名=不结盟运动;
位置=loc;
}
//默认构造函数。
地点(){
name=“Default”;
位置={0.0f,0.0f};
}
//析构函数。此对象不包含指针,因此没有要删除的内容。
~Place(){
}
公众:
void setName(字符串名称){
姓名=不结盟运动;
}
无效设置位置(点loc){
位置=loc;
}
};
类指针位置{
公众:
地点*地点;
公众:
PointerToAPlace(地点*pl){
*地点=*pl;
}
~PointerToAPlace(){
删除位置;
}
};
int main(int argc,字符**argv){
标准::cout
这一开始是错误的。在指向任何地方之前,您正在推迟放置

大概您的意思是
place=pl
*
是类型的一部分,而不是名称

如果您将指针声明写为
Place*pl
,而不是
Place*pl
,那么这对您来说就更清楚了;不要听上世纪70年代的反对者的话,他们总是纠缠于多变量声明的边缘,因为这是这种表示法唯一的缺点

PointerToAPlace(Place *pl) {
    *place = *pl;
}
这是错误的,如果您试图存储指针,则执行以下操作:

PointerToAPlace(Place* pl) {
    place = pl;
}
或者更好地使用构造函数初始值设定项列表:

PointerToAPlace(Place* pl) : place(p1) {
}
您当前的代码没有设置
place
,因此它包含一个垃圾值,指向谁知道在哪里,然后取消引用它(这是未定义的行为)

在复制
指针ToaPlace
时还需要小心,当前如果复制它,会得到两个对象都持有相同的指针,并且都会尝试删除它

我想,一旦你学会了语法的工作原理以及如何使用
new
/
delete
,你应该停止使用它们,转而使用智能指针

/*Trying to do a pointer to an array of objects.*/
Place *placeF[7];

不,这是一个由七个(未初始化的)指向
位置的指针组成的数组。因此,当您取消引用它们时,将得到segfault。

您应该向类中添加一个副本构造函数。 如果没有,当类实例被推到堆栈上时,您将遇到麻烦。 复制构造函数是将同一类实例作为参数的构造函数:

Point(Point & original)
{
  // initialize this with original
}

<>编辑:在代码片段中添加缺失'/'。请问一个具体的问题。你的问题是什么?首先,这不应该编译。<代码> NAMESB <代码>在初始化器中有太多的字符串。不管怎么说,你使用的是未初始化的指针,好像它们指向了一个有效的对象。我也会考虑发布关于如何使用Lang.的提示。使用更好的语言(例如,对于
,您拥有的无用析构函数)为学习C++中创建对象的所有方法以及如何管理它们而不是只使用<代码>新< /代码>,我们经常从java初学者那里看到。一般来说,建议好点,但这不是一个有效的复制构造函数,它需要引用它的参数。否则调用它将尝试复制对象。初始化参数,该参数调用复制构造函数,该参数尝试复制参数,该参数调用复制构造函数,该点不需要复制构造函数。谢谢,我不知道。现在可以正常工作了。:)谢谢。这更有意义,现在一切都在编译/运行。我还将研究复制是如何工作的在C++语言中,指针指向C++。在其他语言中,我总是定义一个特定的复制()方法,用于确保不与任何指针共享任何原始指针。我假设我应该在C++中做同样的操作。这就是复制构造函数所用的。多变量声明是:int i,j,k;或者int i=0,j=0,k=0;对吗?
Point(Point & original)
{
  // initialize this with original
}