Pergunta

Recentemente, eu tenho uma idéia perigosa na minha cabeça depois de ler este post no blog.Essa idéia pode ser expressa assim:

Eu não preciso de mais do que o C++ standard library oferece.Então, por que não implementar um menos geral, mas fácil de usar a versão?

Como um exemplo, usando a STL cospe resmas de incompreensível e desconfigurado erros do compilador.Mas, eu não me importo sobre allocators, iteradores e afins.Então, por que não posso ter um par de horas e implementar um fácil de usar lista ligada de classe, por exemplo?

O que eu gostaria de saber do StackOverflow comunidade é este:quais são os perigos, as possíveis desvantagens e vantagens possíveis para "rolling minha própria" para a maioria das funcionalidades existentes em C++?

Editar: Eu sinto que as pessoas têm compreendido mal-me sobre esta ideia.A ideia era entender se eu poderia implementar um muito pequeno conjunto de STL funcionalidade que é bastante simplificado - se mais como um projeto para ensinar-me sobre estruturas de dados e afins.Eu não propor re-inventar a roda inteira a partir do zero, apenas a parte que eu preciso e quero aprender. Eu suponho que o que eu queria perguntar é se a complexidade de usar a STL garante a criação de menor, mais simples versão de si mesmo.

Re-com impulso ou similar.

Mais do que eu o código é para a Universidade e não estamos autorizados a usar bibliotecas externas.Portanto, é a biblioteca padrão C++, ou minhas aulas.

A objetividade desta questão.

Esta questão é não subjetiva.Nem deve ser da comunidade Wiki, uma vez que não é uma votação.Eu quero concretas, argumentos que destacam uma vantagem ou uma desvantagem que poderia possivelmente ocorrer com a minha abordagem.Ao contrário da crença popular, isso não é opinião, mas com base na experiência ou bons argumentos lógicos.

Formato.

Por favor, poste apenas uma desvantagem ou uma vantagem por resposta.Isso vai permitir que as pessoas para avaliar idéias individuais em vez de todas as suas ideias de uma só vez.

E, por favor...

Sem guerras religiosas.Eu não sou fã boy de qualquer idioma.Eu uso qualquer que seja aplicável.Para gráficos e compressão de dados (o que eu estou trabalhando no momento), que parece ser o C++.Por favor, restringir suas respostas para a pergunta ou o que será votos negativos.

Foi útil?

Solução

Então, por que não implementar um a menos geral, mas fácil de usar a versão?

Porque você não pode.Porque tudo o que você pode dizer sobre o C++, não é uma linguagem simples e, se você já não é muito bom no que faz, a sua lista ligada implementação será buggy.

Honestamente, a sua escolha é simples:

Aprender C++, ou não usá-lo.Sim, C++ é comumente usada para gráficos, mas o Java tem bibliotecas OpenGL também.Faz assim C#, Python e praticamente todos os outros idiomas.Ou C.Você não tem que usar C++.

Mas se você usá-lo, aprendê-lo e usá-lo corretamente.

Se você deseja imutável cadeias de caracteres, crie a sua seqüência de caracteres como const.

E, independentemente de sua implementação subjacente, a STL é extremamente simples de usar.

Compilador de C++ erros pode ser lido, mas é preciso um pouco de prática.Mas mais importante, eles não são exclusivas da STL código.Você vai encontrar-los, não importa o que você faz, e quais bibliotecas você utilizar.Para se acostumar a eles.E se você está se acostumando a eles de qualquer maneira, você pode também usar a STL também.

Além do que, algumas outras desvantagens:

  • Ninguém irá entender seu código.Se você perguntar a uma pergunta ENTÃO sobre std::vector, ou iteradores bidirecionais, todo mundo que está razoavelmente familiarizado com c++ pode responder.Se você perguntar sobre a Minha::CustomLinkedList, ninguém pode ajudá-lo.O que é lamentável, porque a realização de sua própria também significa que não haverá mais erros para pedir ajuda sobre.
  • Você está tentando curar o sintoma, não a causa.O problema é que você não entenda C++.STL é apenas um sintoma disso.Evitando a STL não vai magicamente fazer seu código C++ trabalho melhor.
  • Os erros de compilador.Sim, eles são desagradável de ler, mas eles estão lá.Um monte de trabalho em STL tem ido para assegurar que a utilização incorrecta vai acionar erros do compilador na maioria dos casos.Em C++ é muito fácil fazer o código que compila, mas não funciona.Ou parece funcionar.Ou funciona no meu computador, mas não consegue misteriosamente em outro lugar.A sua própria lista ligada quase que certamente iria mover-se mais erros de tempo de execução, onde eles passam despercebidas por um tempo, e ser muito mais difícil de rastrear.
  • E mais uma vez, será buggy.Confie em mim.Eu já vi muito bom programadores de C++ escrever uma lista encadeada em C++, apenas para descobrir erro após erro, na fronteira obscura casos.E C++ é de todas as fronteiras dos casos.Será que a sua lista ligada lidar com exceção de segurança corretamente?Será que vai garantir que tudo está em um estado consistente se a criação de um novo nó (e, assim, chamar o tipo de objeto do construtor) lança uma exceção?Que não vazamento de memória, que os destruidores vai ser chamado?Será que vai ser tão segurança do tipo?Será que vai ser como a performance?Há um monte de dores de cabeça para lidar com quando escrever recipiente de classes em C++.
  • Você está perdendo um dos mais poderosos e flexíveis de bibliotecas na existência, em qualquer idioma.O STL pode fazer um monte que seria uma dor, mesmo com o Java, o gigante inchado de biblioteca de classe.C++ é bastante difícil, já, não há necessidade de jogar fora as poucas vantagens que ele oferece.

Eu não me importo sobre allocators, os iteradores e similares

Allocators pode ser ignorada com segurança.Você praticamente não precisa nem sabe que eles existem.Iteradores são brilhantes, porém, e vendo-los poupar-lhe um monte de dores de cabeça.Só existem três conceitos que você precisa entender para usar a STL efetivamente:

  • Recipientes:Você já sabe sobre estes.vetores, listas ligadas, mapas, conjuntos, filas e assim por diante.
  • Os iteradores:Abstrações que permitem que você navegue de um recipiente (ou subconjuntos de um contêiner, ou qualquer outra sequência de valor, na memória, no disco na forma de fluxos, ou computadas na mosca).
  • Algoritmos:Comum de algoritmos que trabalham em qualquer par de iteradores.Você tem de classificação, for_each, localizar, copiar e muitos outros.

Sim, a STL é pequeno se comparado ao Java da biblioteca, mas ele traz uma quantidade surpreendente de energia quando você combinar acima de 3 conceitos.Há um pouco de uma curva de aprendizado, porque é incomum biblioteca.Mas se você estiver indo para passar mais de um dia ou dois com C++, vale a pena aprender corretamente.

E não, eu não estou seguindo o seu formato de resposta, porque eu pensei, na verdade, dando-lhe uma resposta detalhada seria mais útil.;)

Editar:

Seria tentador dizer que uma vantagem de rolamento o seu próprio país é que você gostaria de aprender mais sobre o idioma, e talvez mesmo por isso que a STL é uma de suas graças salvadoras..Mas eu realmente não estou convencido de que é verdade.Ele pode funcionar, mas pode virar também.

Como eu disse acima, é fácil escrever código C++ que parece para o trabalho.E quando ele pára de funcionar, é fácil reorganizar algumas coisas, como a declaração, a fim de variáveis, ou inserir um pouco de preenchimento em uma classe, para torná-lo aparentemente o trabalho novamente.O que gostaria de saber a partir de que?Teria que ensiná-lo a escrever melhor C++?Talvez.Mas o mais provável é que tinha acabado de ensinar que "C++ é uma merda".Seria ensinar a você como usar a STL?Definitivamente não.Uma abordagem mais útil pode ser utilizando o incrível poder do StackOverflow em aprender STL o caminho certo.:)

Outras dicas

Desvantagem: Ninguém além de você usará.

Vantagem: No processo de implementá -lo, você aprenderá por que a biblioteca padrão é uma coisa boa.

Advantages: eating your own dogfood. You get exactly what you do.

Disadvantages: eating your own dogfood. Numerous people, smarter than 99 % of us, have spent years creating STL.

I suggested you learn why:

using the STL spits out reams of incomprehensible and mangled compiler errors

first

Disadvantage: you may spend more time debugging your class library than solving whatever university task you have in front of you.

Advantage: you're likely to learn a lot!

There is something you can do about the cryptic compiler STL error messages. STLFilt will help simplify them. From the STLFilt Website:

STLFilt simplifies and/or reformats long-winded C++ error and warning messages, with a focus on STL-related diagnostics (and for MSVC 6, it fully eliminates C4786 warnings and their detritus). The result renders many of even the most cryptic diagnostics comprehensible.

Have a look here and, if you are using VisualC, also here.

I think you should do it.

I'm sure I'll get flambayed for this, but you know, every C++ programmer around here has drunk a little too much STL coolaid.

The STL is a great library, but I know from first hand experience that if you roll your own, you can:

1) Make it faster than the STL for your particular use cases. 2) You'll write a library with just the interfaces you need. 3) You'll be able to extend all the standard stuff. (I can't tell you how much I've wished std::string had a split() method)...

Everyone is right when they say that it will be a lot of work. Thats true.

But, you will learn a lot. Even if after you write it, you go back to the STL and never use it again, you'll still have learned a lot.

Disadvantage : IMHO, reimplimenting tested and proven libraries is a rabit hole which is almost garanteed to be more trouble than it's worth.

A bit of my experience : Not that long ago I have implemented my own vector-like class because I needed good control on it.

As I needed genericity I made a templated array.

I also wanted to iterate through it not using operator[] but incrementing a pointer like a would do with C, so I don't compute the address of T[i] at each iteration... I added two methods one to return pointer to the allocated memory and another that returns a pointer to the end. To iterate through an array of integer I had to write something like this :

for(int * p = array.pData(); p != array.pEnd(); ++p){
  cout<<*p<<endl; 
}

Then when I start to use vectors of vectors I figure out that when it was possible a could allocate a big bloc of memory instead of calling new many times. At this time I add an allocator to the template class.

Only then I notice that I had wrote a perfectly useless clone of std::vector<>.

At least now I know why I use STL...

Another Disadvantage:

If you want to get a C++ job when you're finished with University, most people who would want to recruit you will expect that you are familiar with the Standard C++ library. Not necessarily intimately familiar to the implementation level but certainly familiar with its usage and idioms. If you reimplement the wheel in form of your own library, you'll miss out on that chance. This is nonwithstanding the fact that you will hopefully learn a lot about library design if you roll your own, which might earn you a couple of extra brownie points depending on where you interview.

Disadvantage:

You're introducing a dependency on your own new library. Even if that's sufficient, and your implementation works fine, you still have a dependency. And that can bite you hard with code maintenance. Everyone else (including yourself, in a year's time, or even a month's) will not be familiar with your unique string behavior, special iterators, and so on. Much effort will be needed just to adapt to the new environment before you could ever start refactoring/extending anything. If you use something like STL, everyone will know it already, it's well understood and documented, and nobody will have to re-learn your custom throwaway environment.

You may be interested in EASTL, a rewrite of the STL Electronic Arts documented a while back. Their design decisions were mostly driven by the specific desires/needs in multiplatform videogame programming. The abstract in the linked article sums it up nicely.

Disadvantage : You're university course is probably laid out like this for a reason. The fact that you are irritated enough by it (sarcasm not intended), may indicate you are not getting the paridigm, and will benefit a lot when you have a paradigm shift.

Advantage

If you look into MFC, you'll find that your suggestion already is used in productive code - and has been so for a long time. None of MFC's collection classes uses the STL.

Why don't you take a look at existing C++ libraries. Back when C++ wasn't quite as mature, people often wrote their own libraries. Have a look at Symbian (pretty horrible though), Qt and WxWidgets (if memory serves me) have basic collections and stuff, and there are probably many others.

My opinion is that the complexity of STL derives from the complexity of the C++ language, and there's little you can do to improve on STL (aside from using a more sensible naming convention). I recommend simply switching to some other language if you can, or just deal with it.

As an example, using the STL spits out reams of incomprehensible and mangled compiler errors

The reason for this is essentially C++ templates. If you use templates (as STL does) you will get reams of incomprehensible error messages. So if you implement your own template based collection classes you will not be in any better spot.

You could make non template based containers and store everything as void pointers or some base class e.g. But you would lose compile time type checks and C++ sucks as a dynamic language. It is not as safe to do this as it would be in e.g. Objective-C, Python or Java. One of the reasons being that C++ does not have a root class for all classes to all introspection on all objects and some basic error handling at runtime. Instead your app would likely crash and burn if you were wrong about the type and you would not be given any clues to what went wrong.

Disadvantage: reimplementing all of that well (that is, at a high level of quality) will certainly take a number of great developers a few years.

what are the dangers, possible disadvantages and possible advantages to "rolling my own" for most of the existing functionality in C++?

Can you afford and possibly justify the amount of effort/time/money spent behind reinventing the wheel?

Re-using boost or similiar.

Rather strange that you cannot use Boost. IIRC, chunks of contribution come in from people related to/working in universities (think Jakko Jarvi). The upsides of using Boost are far too many to list here.

On not 'reinventing the wheel'

Disadvantage: While you learn a lot, you also set yourself back, when you come to think of what your real project objectives are.

Advantage: Maintenance is easier for the folks who are going to inherit this.

STL is very complex because it needs to be for a general purpose library.

Reasons why STL is the way it is:

  • Based on interators so standard algorithms only need a single implementation for different types of containers.
  • Designed to behave properly in the face of Exceptions.
  • Designed to be 'thread' safe in multi threaded applications.

In a lot of applications however you really have enough with the following:

  • string class
  • hash table for O(1) lookups
  • vector/array with sort / and binary search for sorted collections

If you know that:

  • Your classes do not throw exceptions on construction or assignment.
  • Your code is single threaded.
  • You will not use the more complex STL algorithms.

Then you can probably write your own faster code that uses less memory and produces simpler compile/runtime errors.

Some examples for faster/easier without the STL:

  • Copy-on-Write string with reference counted string buffer. (Do not do this in a multi-threaded environment since you would need to lock on the reference count access.)
  • Use a good hash table instead of the std::set and std::map.
  • 'Java' style iterators that can be passed around as a single object
  • Iterator type that does not need to know the type of the container (For better compile time decoupling of code)
  • A string class with more utility functions
  • Configurable bounds checking in your vector containers. (So not [] or .at but the same method with a compile or runtime flag for going from 'safe' to 'fast' mode)
  • Containers designed to work with pointers to objects that will delete their content.

It looks like you updated the question so now there are really two questions:

  1. What should I do if I think the std:: library is too complex for my needs?

Design your own classes that internally use relevant std:: library features to do the "heavy lifting" for you. That way you have less to get wrong, and you still get to invent your own coding interface.

  1. What should I do if I want to learn how data structures work?

Design your own set of data structure classes from the ground up. Then try to figure out why the standard ones are better.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top