构造函数中指针指针的默认值问题

时间:2015-03-27 17:02:43

标签: c++ class pointers constructor

当我们使用指向类的“双”指针时,我们在构造函数中用参数写什么?我们是否使用一个指针来分配内存?

这是代码。它不编译,我不明白为什么。谢谢你的帮助。

#include <iostream>
#include <cmath>
#include <cstring>

using namespace std;

class Article{
private:
    char title[100];
    char author[50];
    char *content;
    bool publish;
public:
    Article(char *title="", char *author="", char *content="", bool publish=0){
    strcpy(this->title, title);
    strcpy(this->author, author);
    this->content=new char[strlen(content)+1];
    strcpy(this->content, content);
    this->publish=publish;
    }
    void show(){
        cout<<title<<endl;
        cout<<author<<endl;
        cout<<content<endl;
    }
    ~Article(){
        delete [] content;
    }
};

class Newspaper{
private:
    char name[100];
    Article **p;
    int articles;
    Article first;
public:
    Newspaper(char *name="", Article **p=Article(), int articles=0, Article first=Article()){
        strcpy(this->name, name);
    }

};

int main() {
    char title[100], author[50], content[100];
    int n;
    cin >> n;
    char name[100];
    cin.getline(name, 100);
    cin.getline(name, 100);

    Article first("VAZNO","OOP","Vezba:OOP",true);
    Newspaper v(name,first);
    Article **s = new Article*[n];
    for(int i = 0; i < n; ++i) {
        cin.getline(title, 100);
        cin.getline(author, 50);
        cin.getline(content, 100);
        v.addArticle(Article(title, author, content, true)); //se koristi copy konstruktor
    }
    v.showFirst();
    v.showLongest();
    cout << v.totalofauthor(author) << endl;
    for(int i = 0; i < n; ++i) {
        delete s[i];
    }
    delete [] s;
        return 0;

    }

1 个答案:

答案 0 :(得分:4)

您问题的解决方案:

从您的代码中可以看出Newspaper使用指向指针的指针(您称之为双指针)来跟踪Articles

    Newspaper(char *name, Article **p ,                       // This would be ok
                 int articles = 0, Article first = Article())  

但是你很难为它定义一个默认参数:

    Newspaper(char *name="", Article **p=Article(),          // oops doesn't compile 
                 int articles = 0, Article first = Article())  

原因是“双”指针与对象本身不同。如果您想在此处使用默认参数,则还必须提供双指针。

此代码正是如此:

    Newspaper(char *name = "", Article **p = new Article*,    // this is ok !
                 int articles = 0, Article first = Article()){

所以这是你问题的解决方案。

但你的问题是什么?

但是目的是什么或提供一个虚拟指针,指向无处默认参数?

稍后您尝试再次根据文章创建Newspaper

    Newspaper v(name, first);   // won't work, because first is not a pointer either 

所以问题不是构造函数,而是整个原则。您似乎确实希望基于Newspaper创建Article,并且您使用默认值来涵盖有人想要创建Newspaper而不是Article的情况。

显然,您的设计还预见到Articles可以动态添加:

    v.addArticle(Article(title, author, content, true)); 

最后看起来你的指针确实存在问题:在你编写的构造函数中,你没有将poitner初始化为足够大的内存区域来保存名称:

 Newspaper(char *name = "", ...) { 
    strcpy(this->name, name);    // Ouch !!  pointer name is not initalized !  
 }

因此,一旦您编译完代码,您的程序就无法运行!由于this->name是一个从未初始化的指针,因此strcpy()会导致内存损坏和未定义的行为(崩溃!?)。

建议

首先,获取一本书或教程来理解和掌握指针。如果你不这样做,你很快就会完全迷失在你的C ++课程中。

在此期间,请删除char*strcpy()等,然后使用 std::string

最后,请考虑使用 std::vector 来管理动态Article容器。使用Article**实现的动态poitner数组需要额外的逻辑,例如在文章数量增加时保持大小,重新分配内存,而不是说你放入的文章的所有权(分配/解除分配)。阵列。

根据这些建议,您的Newspaper将如下所示:

class Newspaper{
private:
    string name;
    vector<Article> p;   // p.size() will provide the number of articles 

public:
    Newspaper(string name = "") : name(name) { }  // empty newspaper 
    Newspaper(string name, Article& a) : Newspaper(name) {  // combo
        addArticle(a); 
        }
    void addArticle(Article &a) {
        p.push_back(a);                // add and article to the vector
    }
    ... // rest of the code, here
};

here多一点