zoukankan      html  css  js  c++  java
  • stackoverflow上的一个关于传递类对象的问题

    今天在stackoverflow上看到有一个这样提问

    说下面这段程序第二个输出语句有问题

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    class C {
    public:
    char* s;
    C(char* s_) {
    s=(char *)calloc(strlen(s_)+1,1);
    strcpy(s,s_);
    };
    ~C() {
    free(s);
    };
    };

    void func(C c) {};

    void main() {
    C o="hello";
    printf("hello: %s\n",o.s); // works ok
    func(o);
    printf("hello: %s\n",o.s); // outputs garbage
    };


    我看了以后,大概分析了一下,原因是这样的

    在c++中如果如果我们给一个类的对象赋值,或当形参传给其他函数时,假如类中含有指针类型的变量,默认c++会为我们拷贝指针而不会拷贝指针指向的内容。

    上面的例子中,

     func(o);
    这个函数将实参o传给了形参,但是由于o的成员s是指针,所以实参与形参的指针指向了同一块内存空间,但是形参在函数结束后就析构掉了,
     free(s);同时把指向的内存空间也清除了,所以当主程序再次返回的时候,原来的指针指向的内存空间已经没有了数据,故输出错误。
    下面是一个外国同行写的解决方案
    #include <iostream>

    class C {
    std::string s;
    C(const std::string& s_)
    : s(s_){}
    };

    std::ostream& operator<<(std::ostream& os, const C& c){
    return os << c.s;
    }

    void func(C& c){
    // do what you need here
    }

    int main(){
    C c("hello");
    std::cout << c << '\n';
    func(c);
    std::cout << c << std::endl;
    return 0;
    }
    他这样的写法,是从另外一个角度写的,没有解决了指针的问题,其实,我感觉更好的方法是写一个复制构造函数,去专门管理指针的赋值。这样就不会容易出错了。

  • 相关阅读:
    几种常用的曲线
    0188. Best Time to Buy and Sell Stock IV (H)
    0074. Search a 2D Matrix (M)
    0189. Rotate Array (E)
    0148. Sort List (M)
    0859. Buddy Strings (E)
    0316. Remove Duplicate Letters (M)
    0452. Minimum Number of Arrows to Burst Balloons (M)
    0449. Serialize and Deserialize BST (M)
    0704. Binary Search (E)
  • 原文地址:https://www.cnblogs.com/gaoteng/p/2388531.html
Copyright © 2011-2022 走看看