动态对象数组在C++和Java中有何不同?



我最近了解了Java中的对象数组。考虑一下:

Student s[]=new student[3];

但是为什么上面的语句只创建可以保存对 3 个学生对象的引用的数组。它不会自行创建学生类对象。我必须使用 Student 类的构造函数单独创建它们。 因此,如果我尝试访问任何这样的类成员:

s[0].name="meet"

它将生成运行时错误"空指针异常"

但这些对我来说似乎很奇怪,因为C++这些都不是必需的。考虑这个C++程序。

#include <iostream>
using std::cout;
class Test
{
    public:
        Test()
        {
            cout<<"Constructorn";
        }
        void fun()
        {
            cout<<"fun() is calledn";
        }
        ~Test()
        {
            cout<<"Destructorn";
        }
};
int main()
{
    Test* t=new Test[3];
    for(int i=0;i<3;i++)
        t[i].fun();
    delete[] t;
    return 0;
}

当 main() 中的第一个语句执行时内部会发生什么? 如果它在C++中工作正常,那么为什么要在 Java 中生成 NullPointerException。

   class test
    {
          test()
          {
                 System.out.println("Constructor");
          }
          void fun()
          {
                 System.out.println("fun() is called");
          }
           public static void main(String args[])
           {
                 test t[]=new test[3];
                 for(int i=0;i<3;i++)
                       t[i].fun();  // oops runtime error
                 for(int i=0;i<3;i++)
                       t[i]=new test();
                 for(int i=0;i<3;i++)
                       t[i].fun();  // now fine.
           }
}

为什么必须在java中使用类的构造函数单独创建对象,而不需要使用C++中的类构造函数单独创建它们?

请帮助我。

简短的回答只是因为语法(几乎相同)并不意味着它的工作方式相同。 事实上,正如您编写的那样,该语句不会在C++中编译,因为 [] 在 Student s[]

Java 代码的等效C++代码为:

Student** s = new Student*[3];

然后,您可以像这样初始化学生:

s[0] = 新生("吉米");

这是一个需要掌握的重要概念,因为Java并不是唯一以这种方式与C++不同的编程语言。

这是一个完整的示例,您可以尝试一下。 使用 g++ 4.3.2 编译

#include <iostream>
#include <string>
class Student {
public:
    Student() : name_("<unknown>") {
        std::cout << "Default constructor called" << std::endl;
    }
    Student(const char* name) : name_(name) {
        std::cout << "constructor called with name '" << name << "'" << std::endl;
    }
    void setName(const std::string& name) { name_ = name; }
    const std::string& getName() const { return name_; }
private:
    std::string name_;
};
void demoArrayOfValues() {
    std::cout << "demoArrayOfValues()" << std::endl;
    // Here the default constructor will be called 3 times because
    // creating you're creating an array of objects
    Student* s =  new Student[3];
    for (int x = 0; x < 3; ++x) {
        std::cout << "Student[" << x << "] (byValue): " << s[x].getName() << std::endl;
    }
    s[0].setName("Jimmy");
    s[1].setName("Sally");
    s[2].setName("Susie");
    for (int x = 0; x < 3; ++x) {
        std::cout << "Student[" << x << "] (after setting): " << s[x].getName() << std::endl;
    }
    std::cout << std::endl;
}
void demoArrayOfPointers() {
    std::cout << "demoArrayOfPointers()" << std::endl;
    // This is the C++ equivalent of the Java example that started the question
    // Here you're creating an array of pointers and have to create the objects
    // themselves
    Student** s =  new Student*[3];
    for (int x = 0; x < 3; ++x) {
        std::cout << "Student[" << x << "] (pointer): " << s[x] << std::endl;
    }
    s[0] = new Student("Jimmy");
    s[1] = new Student("Sally");
    s[2] = new Student("Susie");
    for (int x = 0; x < 3; ++x) {
        std::cout << "Student[" << x << "] (after creating): " << s[x]->getName() << std::endl;
    }
    std::cout << std::endl;
    // Now we iterate over the elements in the array and delete each one.       
    for (int x = 0; x < 3; ++x) {
        delete s[x];
    }
    // Now we delete the array itself
    delete [] s;
}
int main(int argc, const char** argv) {
    demoArrayOfValues();
    demoArrayOfPointers();
    return 0;
}

最新更新