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;
    }
    他这样的写法,是从另外一个角度写的,没有解决了指针的问题,其实,我感觉更好的方法是写一个复制构造函数,去专门管理指针的赋值。这样就不会容易出错了。

  • 相关阅读:
    inotify+rsync做实时同步
    JAVA序列化和反序列化
    初识iBatis
    《Spring in action》之高级装配
    《Spring in action》之装配Bean
    原根
    数论知识
    线性(欧拉)筛
    Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals) E DNA Evolution
    Fibonacci
  • 原文地址:https://www.cnblogs.com/gaoteng/p/2388531.html
Copyright © 2011-2022 走看看