¿Clases de alcance y aprobación por valor? [duplicar]

Posible duplicado:
¿Qué es la regla de tres?

The following code outputs garbage at best or crashes:

#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
};

I really wonder why - the object should not even be touched because Im passing it by value ...

preguntado el 09 de marzo de 12 a las 15:03

También, trabaja para POR FAVOR, refrain from coding "C with Classes"... PLEASE! -

@James: Because it's everything that is bad in this (the C++) world. -

@Xeo Why force your opinion down his throat? Some people like to write C with the structural benefits C++ classes provide, and there's nothing wrong with that. The oh-so-perfect STL and boost aren't available everywhere and don't necessarily suit every application. -

@JamesMcLaughlin: You're right. But "not everywhere" and "don't suit every application" requires a sense of perspective- that is, "not everywhere" meaning "Only not available on very minor embedded platforms" and "don't suit every application" meaning "Might not suit 0.00001% of applications"- i.e., whilst both are technically true, in reality, such questions are much too localized and it's perfectly reasonable to assume that they are available and do suit. -

@JamesMcLaughlin this type of code is utter crap and it is what tars the name of C++ as a horrible messy language. It also makes up half of the C++ question on stackoverflow (or at least bad style in general) that wouldn't have occurred otherwise. The reason C++ was created was to get away from that type of code with useful abstractions. -

1 Respuestas

everthing about your code is bad in the eyes of C++, sorry. try this

#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;
}

In this example you don't have to worry about memory allocation and destruction, printf format strings or strcpy. It is much more robust.

C with classes (which is what you are writing) is categorically wrong, and blindly ignores the features that were created to make the language safer and easier without overhead.

respondido 09 mar '12, 15:03

i agree this is correct way, but I still wonder exactly why original code crashes. probably double free() - Nick

I know this is old... but thinking about the crash, it could be that the instance of the new "C" class that's created after the copy operation when 'func(o)' is called will call "free(..)" on 's', which has not been initialized. Automatic lifetime will call the destructor when 'func' exits, which calls free on an uninitialized 's'. Maybe. - Sean Aitken

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.